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

时间:2015-05-12 08:51:57

标签: c segmentation-fault malloc strncpy

为什么......

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);

提供 segfault

另外,这是怎么回事:

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

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

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:1)

不同之处在于,您在以后的情况下初始化为指针 dst src 的字符串文字存储在数据段中。数据段是程序虚拟地址空间的一部分,它包含由程序员初始化的全局变量和静态变量。

该段可以进一步分为初始化只读区域和初始化读写区域。

例如由

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

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

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

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

在上述案例中......

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

相当于

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

char* dst = &temp[0];

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

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

它取决于编译器。