以下代码总是分段故障:
char *test3 = (char *) malloc(sizeof(char) * 5);
test3 = "asdf";
printf("%sn", test3);
以下代码未分段故障:
char *test3 = (char *) malloc(sizeof(char) * 5);
test3[0] = 'a';
test3[1] = 'b';
test3[2] = 'c';
test3[3] = 'd';
test3[4] = ' ';
printf("%sn", test3);
我想问题可能是如何将cstring文字分配给动态创建的cstring?
"填充"字符串的正确方法是:
strcpy(test3, "abcd");
然而,我强烈建议你不要使用malloc
[并且绝对不要使用(char *) malloc(...)
-因为这会隐藏一些相当讨厌的bug,它们会在适当的时候跳起来咬你,因为bug确实有这样做的倾向-你这样做可能是因为你把C代码编译成C++代码,这是错误的,并教会你这样的坏习惯]。
使用malloc
来分配小字符串是对空间的巨大浪费。您的5个字符的字符串可能有16-32个字节的开销,并且将四舍五入到8或16个字节。因此,总共可以使用48个字节来存储5个字节——这是对空间的巨大浪费。
其他人(正确地)建议您将字符串复制到分配的内存中。
这就是为什么您的方法是分段错误:字符串"asdf"是一个字符串文字,在编译时它存储在rodata或只读数据中。当您的程序尝试时
test3 = "asdf";
它试图创建一个指向rodata的指针。C不允许指针指向rodata,因此您的语句不仅不起作用,而且还会出现seg错误。
第二种方法很好,因为您不是在修改指针,而是在修改它指向的内容。
首先,感谢您提出这个问题——它有一个有趣的褶皱。
我用Eclipse/Microsoft C运行了您的代码,但没有得到分段错误,它按预期打印了"asdf"。
然而,这并不意味着或暗示你没有得到一个分割错误。您的结果意味着要检查编译器如何实现以下两个语句:
char *test3 = (char *) malloc(sizeof(char) * 5);
在堆上分配存储,并将指针test3
设置为指向该位置。下一条语句还会更新相同的指针。
test3 = "asdf";
然而,在这种情况下,test3
指向存储该文本的文本"asdf"。有些编译器生成字符串的文本池,并将其存储在可执行文件中的某个位置,因此对于某些编译器来说,这些文本是无法修改的。
那么,编译器为什么要将文字存储在无法访问的地方呢?没有意义,因此问题来了:你用的是什么C编译器?它坚持什么版本的C??
要解决可能是编译器错误的问题,并且仍然将test3
指向文字,请尝试??(同样,C编译器在实现语言结构的内容和方式上确实有所不同。)
const char *literal = "asdf"; // also try without a const stmt
// other code here
test3 = literal;
最后,在第二个示例中,堆上malloc
ed的存储正在被修改,并且显然是可寻址的。
在您的情况下,不能用"="分配字符串值。
您需要使用strcpy或sprintf函数。在程序结束时(或者当字符串不再使用时)不要忘记释放它!例如:
#define BUFSIZE 5
int main(void) {
char *test3 = malloc(sizeof(char) * BUFSIZE);
snprintf(test3,BUFSIZE,"test");
printf("%sn", test3);
free(test3);
return 0;
}
或者你可以写:
int main(void) {
char buf[BUFSIZE] = "test";
printf("%sn", buf);
return 0;
}