为什么故意不正确地使用strcpy不会失败呢?

Gab*_*azo 11 c malloc strcpy

为什么以下C代码使用strcpy对我来说很好?我尝试以两种方式使其失败:

1)我尝试strcpy从字符串文字到分配的内存太小而不能包含它.它复制了整件事并且没有抱怨.

2)我尝试strcpy了一个未被NUL终止的数组.在strcpyprintf工作就好了.我原本以为strcpy复制了chars直到NUL找到了,但没有一个存在,它仍然停止.

为什么不这些失败?我是以某种方式获得"幸运",还是我误解了这个功能是如何工作的?它是特定于我的平台(OS X Lion),还是大多数现代平台以这种方式工作?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char *src1 = "123456789";
    char *dst1 = (char *)malloc( 5 );

    char src2[5] = {'h','e','l','l','o'};
    char *dst2 = (char *)malloc( 6 );

    printf("src1: %s\n", src1);
    strcpy(dst1, src1);
    printf("dst1: %s\n", dst1);
    strcpy(dst2, src2);
    printf("src2: %s\n", src2);
    dst2[5] = '\0';
    printf("dst2: %s\n", dst2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行此代码的输出是:

$ ./a.out   
src1: 123456789
dst1: 123456789
src2: hello 
dst2: hello
Run Code Online (Sandbox Code Playgroud)

abe*_*nky 19

首先,复制到一个太小的数组:

C对于超越数组边界没有任何保护,因此如果没有任何敏感信息dst1[5..9],那么你很幸运,并且副本会进入你不正确拥有的内存,但它也不会崩溃.但是,该内存不安全,因为它尚未分配给您的变量.另一个变量可能会分配给它的内存,然后覆盖你放在那里的数据,以后破坏你的字符串.

其次,从非空终止的数组复制:

即使我们通常被教导内存中充满了任意数据,但它的大量内容都是零.即使没有把一个空终止符src2,有很好的机会src[5]恰好是\0反正.这使得复制成功.请注意,这保证,并且可能在任何时候在任何平台上运行失败.但是这次你很幸运(也许大部分时间都是这样),而且它很有用.

  • `NULL`是(扩展为的宏)*null指针常量.它不应该用于引用null或NUL字符,'\ 0'.短语"null终止符"就可以了. (4认同)

Alo*_*ave 14

覆盖超出已分配内存的范围会导致未定义的行为.
所以在某种程度上,你很幸运.

未定义的行为意味着任何事情都可能发生,行为无法解释为定义语言规则的标准,不定义任何行为.

编辑:
在第二个想法,我会说你真的很不走运,程序运行正常,不会崩溃.它现在起作用并不意味着它总会起作用,事实上它是一个炸弹炸毁的炸弹.

根据墨菲定律:
" 任何可能出错的东西都会出问题 " ["并且最有可能在最不方便的时刻"]

[ ]- 我的法律编辑:)