【问题标题】:Predefined string segfaults when copied to by strncpy()由 strncpy() 复制到时的预定义字符串段错误
【发布时间】:2015-05-12 08:51:57
【问题描述】:

为什么……

char *dst = (char*) malloc(sizeof(char) * 11);
char *src = "ABCDEFGHIJKLMNOPQRSTUVQXYZ";
strncpy(dst, src, 10);

... 工作正常,但是...

char *dst = "ABCDEFGHIJ\0";
char *src = "ABCDEFGHIJKLMNOPQRSTUVQXYZ\0";
strncpy(dst, src, 10);

...甚至...

char *dst = "ABCDEFGHIJ\0";
char *src = "KLMNOPQRST\0";
strncpy(dst, src, 10);

给出段错误

另外,这是怎么回事:

char *dst = (char*) malloc(sizeof(char) * 10); // also works with 9
char *src = "ABCDEFGHIJKLMNOPQRSTUVQXYZ\0";
strncpy(dst, src, 10);

将 11 个字节复制到分配有 10 个字节的指针中,原则上应该会失败吗?

【问题讨论】:

    标签: c segmentation-fault malloc strncpy


    【解决方案1】:

    字符串字面量可以存储在只读内存段中。你不应该修改它们。

    此外,没有检查超出范围的写入。您听说的许多安全问题都源于这样一个事实,即有很多代码没有任何边界检查。

    写入超出分配内存的范围,以及尝试修改字符串文字或其他只读/常量数据,会导致undefined behavior

    【讨论】:

      【解决方案2】:

      不同的是,后面的例子中你初始化为指针dstsrc的字符串字面量是存储在数据段中的。数据段是程序虚拟地址空间的一部分,包含了程序员初始化的全局变量和静态变量。

      这个段又可以分为初始化只读区和初始化读写区。

      比如

      定义的全局字符串
      char s[] = “hello world” 
      

      在 C 和 C 语句如 int debug=1 之外的主要(即全局)将存储在初始化的读写区域中。还有一个像

      这样的全局 C 语句
      const char* string = “hello world”
      

      使字符串字面量“hello world”存储在初始化的只读区域中,并将字符指针变量字符串存储在初始化的读写区域中。

      而在上述情况下……

      char* dst = " ABCD........." ;
      

      等价于

      const temp[]="ABCD......";
      
      char* dst = &temp[0];
      

      因此 dst 指向的临时数组将存储在只读内存中,因此您无法对其进行编辑...

      同样在最后一种情况下,即使您可以将 11 个字节复制到指向 10 个字节的指针中,您也会在运行时遇到麻烦……例如:尝试释放指针,您将面临分段错误…… (未定义的行为)。

      它依赖于编译器。

      【讨论】:

      • 欣赏详尽的解释!但是,这样做是否安全?字符 *s = "嘿"; printf("%s %p\n", s, &s); s = "你在那里"; printf("%s %p\n", s, &s);重新分配后它指向同一个地址:嘿 0x7fffb4a809e8 你在那里 0x7fffb4a809e8 (不是说它是同一件事,我只是好奇)
      • 是的,这样做是安全的。因为您没有更改字符串文字“嘿”...相反,您只是在内存中创建一个新字符串“you there”并询问指针s 指向它...另外 &s 是变量 s 的地址,而不是它指向的字符串字面量的地址...
      猜你喜欢
      • 2019-09-25
      • 2012-06-17
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多