【问题标题】:Using strcpy() in C, difference between stack and heap?在 C 中使用 strcpy(),堆栈和堆之间的区别?
【发布时间】:2016-03-18 06:17:09
【问题描述】:

我在使用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是栈和堆。谁能解释一下?

谢谢。

【问题讨论】:

  • 您尝试写入字符串文字。它们既不是栈也不是堆,它们是不可写的。
  • src is a address as well, the only thing it diff from des of line 21 is stack and heap 不,这不是真的。
  • 编译器供应商何时会停止这种做法? char *src = "123456"; 将 const char 数组地址分配给非 const 指针。我们已经有 20 多年的时间来修复旧程序,最坏的情况是编译器选项可能会覆盖默认值并允许这种草率。
  • 发布带有行号的代码不受欢迎,它妨碍了轻松剪切和粘贴到源文件中进行测试。请避免。

标签: c string heap-memory stack-memory


【解决方案1】:

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

C 标准并没有明确指定字符串字面量的分配位置(它不太关心机器的细节),但没有理由假设在静态共享单个全局对象时它会在堆栈上空间(您忘记的第三个主要分配区域)也可以。

更仔细地查看您的代码:

char* src = "0123456789";

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

如果你这样做了:

char src[] = "0123456789";

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

【讨论】:

  • 谢谢,你的代码运行良好,如果我是对的,它让我想到了一个叫做数据段(.data)的东西。我的代码是不是因为写了 .data 的数据而迷恋?
  • 这超出了 C 作为一门语言的范围,进入了编译器选择执行的领域。所有语言都说不要写入字符串文字。它被广泛认为是语言定义中长期存在的“错误”,它们具有元素类型 char 而不是 const char(这与 C++ 不同)。
猜你喜欢
  • 1970-01-01
  • 2016-05-28
  • 2011-03-29
  • 2011-08-30
  • 2018-07-04
  • 2012-02-17
  • 2021-05-10
  • 2021-03-12
相关资源
最近更新 更多