在C中使用strcpy(),堆栈和堆之间的区别?

时间:2015-12-12 10:20:45

标签: c string stack heap

我在使用libc的strcpy()时遇到了问题,这里是代码:

 16 int main(int argc, char *argv[])
 17 {    
 18     char* src = "0123456789";
 19     char* des = (char*) malloc(strlen(src) + 1);
 20      
 21     des = strcpy(des, src);                                                                                                                          
 22     des = strcpy(src, "1010101");
 23      
 24     printf("%s\n", des);
 25     return 0;
 26 }    

我想检查当目标字符串在堆栈中或堆中时strcpy是否正常工作,因此您将看到第21行和第22行。

事实证明,第21行运行良好,但程序在进入第22行时会抛出一个SEGMENTATION FAULT。还有什么,我已调试到libc,我发现它在这一行崩溃:

91         while ((*dest++ = *src++) != '\0')

目前还不是很清楚它在哪一点上粉碎,所以我将这一个语句拆分成几个并使它们与第91行具有相同的功能。我将在这里省略那段代码,最后它崩溃了在* dest的任务。

所以在这里我无法理解它崩溃的原因。在第22行, src 也是一个地址,唯一不同于第21行的 des 是堆栈和堆。谁能解释一下呢?

感谢。

1 个答案:

答案 0 :(得分:1)

  

在第22行,src也是一个地址,它与第21行des的唯一区别是堆栈和堆。

C标准并没有准确地指定字符串文字的分配位置(它并不关心机器的细节),但是没有理由认为它会在堆栈中在静态空间中共享单个全局对象(第三个主要分配区域,您已经忘记了)也可以正常工作。

更仔细地查看您的代码:

char* src = "0123456789";

src是位于堆栈上的单个指针变量。但是你已经用另一个对象的地址填充了该指针,并且字符串文字可能在任何地方,因为每次调用函数时编译器都会重新分配它。

如果你这样做了:

char src[] = "0123456789";

src上的不同语法表示您希望它是一个数组,而不是指向其他地方的数组的指针。 现在将在堆栈上分配一个字符串,并使用 文本"0123456789"填充数据,但不会是与它相同的对象。你可以写这个版本的src没问题,因为它实际上每次都会分配并填充一个新数组,因为你已明确要求它这样做。