当前位置:  开发笔记 > 编程语言 > 正文

为什么strcpy会触发全局变量的分段错误?

如何解决《为什么strcpy会触发全局变量的分段错误?》经验,为你挑选了3个好方法。

所以我有一些C代码:

#include 
#include 

/* putting one of the "char*"s here causes a segfault */
void main() {
  char* path = "/temp";
  char* temp;
  strcpy(temp, path);
}

这样编译,运行和行为就像它看起来一样.但是,如果将一个或两个字符指针声明为全局变量,则strcpy会导致分段错误.为什么会这样?显然我对范围的理解有误.



1> DGentry..:

正如其他海报所提到的,问题的根源在于临时未初始化.当在堆栈上声明为自动变量时,它将包含该内存位置中发生的任何垃圾.显然,对于正在运行的编译器+ CPU + OS,该位置的垃圾是一个有效的指针.strcpy"成功",因为它不会发生段错误,但实际上它将字符串复制到内存中其他位置的任意位置.这种内存损坏问题引起了各地C程序员心中的恐惧,因为它非常难以调试.

将临时变量声明移动到全局范围时,它将被置于BSS部分并自动归零.尝试取消引用*temp然后导致段错误.

将*path移动到全局范围时,*temp会向上移动堆栈上的一个位置.该位置的垃圾显然不是有效指针,因此取消引用*temp会导致段错误.



2> Torlack..:

temp变量不指向任何存储(内存),并且它未初始化.

如果temp被声明为char temp[32];那么代码无论在何处被声明都可以工作.但是,像这样用固定大小来声明temp还有其他问题,但这是另一天的问题.

现在,为什么在全局声明而不是本地声明时会崩溃.运气...

在本地声明时,temp的值来自当时堆栈上可能存在的值.幸运的是,它指向一个不会导致崩溃的地址.然而,它正在摧毁其他人使用的内存.

全局声明时,在大多数处理器上,这些变量将存储在将使用需求零页的数据段中.因此char *temp看起来好像是宣布的char *temp=0.



3> terminus..:

你忘了分配和初始化temp:

temp = (char *)malloc(TEMP_SIZE);

只要确保TEMP_SIZE足够大.你也可以在运行时计算它,然后确保大小足够(至少应该是strlen(path))

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有