2011-02-14 55 views
2

我有一个非常简单的程序,但是这给了我一个seg故障。我一直在努力解决这个问题。请帮忙。std ::用指针交换给出了分段错误

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <vector> 

main() { 
char *database; 
int ndata=4; 
database="aaa4baa3bcd2aab5"; 
char *dummy; 
dummy=(char *)malloc(16); 
memcpy(dummy,database,16); 
printf("%s\n",dummy); 
std::swap(database,dummy); 
dummy[2]='a'; 
} 

在交换工作正常之前分配到虚拟变量。交换后有什么问题。 感谢

回答

1

我会重写你的代码有点不改变其含义

char *database = "aaa4baa3bcd2aab5"; 
char *dummy = (char *)malloc(16); 
memcpy(dummy,database,16); 
printf("%s\n",dummy); 
std::swap(database,dummy); 
dummy[2]='a'; //here you in fact attempt to modify a string literal 

你做了之后swapdummy点,其中database前面所指出,这就是一个字符串文字,你是不允许修改的地址。

此外请注意,字符串文字有16个字符加上一个空终止符 - 总共17个字符,所以一旦你分配了大小为16的缓冲区并复制了文字,那么结果不是空终止。

3

database指向一个字符串文字,它被放入只读存储器,你不能写,即使指针char *,而不是const char*类型。严格地说,文字是const char *类型,并且对char *类型指针的分配应该是不允许的,但这是今天仍然允许的遗留隐式转换。

swap只交换指针本身,而不是它们指向的内容。因此,在swap之后,虚拟指的是包含字符串文字的内存,不允许您写入。

也许你应该考虑使用std::string作为你的字符串处理,它允许简单的赋值等,从而允许swap按照你的预期工作。

+0

+1,来自`char const *`的`char *`真的很烦人......使用`string`! – 2011-02-14 14:20:12

0

字符串文字是不可变的,而尝试修改该字符串可能会导致运行时失败。尽管语言允许char*指向字符串,但在这种情况下,您应该始终标记指针对象常量:const char* database = "aaa4baa3bcd2aab5";

如果这样做,编译器会通知您不能交换这些指针(因为现在它们的类型不兼容),从而避免了查找运行时错误的麻烦。


除此之外,不应将dummy作为字符串打印,因为它不是空终止的。

0

数据库包含17个字符:16个数加上最后的'\ 0'。你只复制前16个,所以虚拟不包含最后的'\ 0'。

因此printf("%s\n",dummy);将读取过去的虚拟结束,并可能访问内存不允许读取。