由 strncpy() 复制到时的预定义字符串段错误

Predefined string segfaults when copied to by strncpy()

为什么...

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

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

char *dst = "ABCDEFGHIJ[=11=]";
char *src = "ABCDEFGHIJKLMNOPQRSTUVQXYZ[=11=]";
strncpy(dst, src, 10);

...甚至...

char *dst = "ABCDEFGHIJ[=12=]";
char *src = "KLMNOPQRST[=12=]";
strncpy(dst, src, 10);

给出段错误?

另外,这是怎么回事:

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

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

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

此外,没有检查越界写入。您听说过的许多安全问题都是因为有很多代码没有进行任何边界检查。

超出分配内存范围的写入,以及试图修改字符串文字或其他 read-only/constant 数据,会导致 undefined behavior

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

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

例如

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

在C语言中,在main(即global)之外的int debug=1之类的C语句会被存储在初始化的读写区中。还有像

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

使字符串文字“hello world”存放在初始化的只读区,字符指针变量string存放在初始化的读写区

在上面的例子中……

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

等同于

const temp[]="ABCD......";

char* dst = &temp[0];

所以 dst 指向的临时数组将存储在只读内存中,因此您无法编辑它...

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

它依赖于编译器。