【发布时间】:2020-09-16 08:25:33
【问题描述】:
如果我使用strcpy 为数组分配字符串字面量,我可以轻松访问超出数组边界的那些字节:
char sequence[4];
strcpy(sequence, "String");
printf("&sequence == %p\n", &sequence);
printf("&sequence[3] == %p\n", &sequence[3]);
printf("The out-of-range values are '%c' and '%c'\n", *(char*)0x000000000022FE50, *(char*)0x000000000022FE51);
&sequence == 000000000022FE4C
&sequence[3] == 000000000022FE4F
The out-of-range values are 'n' and 'g'
但是如果我只是在原地初始化数组就做同样的事情,这些内存字节是空的或者有一些意想不到的值:
char sequence[4] = "String";
printf("&sequence == %p\n", &sequence);
printf("&sequence[3] == %p\n", &sequence[3]);
printf("The out-of-range values are '%c' and '%c'\n", *(char*)0x000000000022FE50, *(char*)0x000000000022FE51);
&sequence == 000000000022FE4C
&sequence[3] == 000000000022FE4F
The out-of-range values are ' ' and 'r'
为什么strcpy和直接存储有这么大的区别?
免责声明: 我知道这个程序不正确。我知道什么是未定义的行为,我知道这是不好的,不应该被视为解决方案。问题仅与机制有关,仅寻求教育目的。我永远不会将此应用于任何实际任务(如果有人担心的话)。
【问题讨论】:
-
char sequence[4]的初始化正好写入 4 个字节。函数调用strcpy(sequence, "whatever")写入与"whatever"中一样多的字节(调用UB) -
@pmg
strcpy不接受数组作为指针吗?也许这就是答案 -
就
strcpy()而言,它只接收指针。调用者发送的数组被编译过程自动转换为指针 -
你用的是什么编译器?不是抱怨
char sequence[4] = "String";吗?!?!这是违反约束的! -
@AnttiHaapala 一些编译器可能会发出警告。实际上没有像 Java 那样的边界检查,人们应该始终注意它们的数组边界