为什么会出现这种故意不正确使用的strcpy不可怕的失败? [英] Why does this intentionally incorrect use of strcpy not fail horribly?

查看:305
本文介绍了为什么会出现这种故意不正确使用的strcpy不可怕的失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么使用的strcpy 的C以下code工作得很好,给我吗?我试图使它失败有两种方式:

1),我试过的strcpy 从字面到分配的内存中的字符串是太小,无法容纳它。它复制了整个事情,并没有抱怨。

2)我试图的strcpy 从一个数组,这不是 NUL 封端。在的strcpy 的printf 工作就好了。我原以为的strcpy 复制字符取值直到 NUL 被发现了,但没有一个是present,它仍然停了下来。

为什么不把这些失败?我只是得到幸运在某种程度上,还是我误解这个功能是如何工作的?它是具体到我的平台(OS X Lion中),还是最现代的平台上以这种方式工作?

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;诠释主(){
    字符* SRC1 =123456789;
    字符* DST1 =(字符*)malloc的(5);    焦炭SRC2 [5] = {'H','E','L','L','O'};
    字符* DST2 =(字符*)malloc的(6)    的printf(SRC1:%S \\ n,SRC1);
    的strcpy(DST1,SR​​C1);
    的printf(DST1:%S \\ n,DST1);
    的strcpy(DST2,SRC2);
    的printf(SRC2:%S \\ n,SRC2);
    DST2 [5] ='\\ 0';
    的printf(DST2:%S \\ n,DST2);    返回0;
}

运行此code的输出是:

  $ ./a.out
SRC1:123456789
DST1:123456789
SRC2:你好
DST2:你好


解决方案

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

C有换去过去的数组边界没有保护,所以如果没有什么敏感的 DST1 [5..9] ,那么你得到的幸运和副本保存到内存中,你不合法拥有,但它不会崩溃无论是。然而,该存储器是不是安全的,因为它没有被分配给您的变量。另一个变数可能有分配给它的内存,后来改写你把在那里的数据,以后损坏您的字符串。

其次,从数组,它是不是空终止复制:

即使我们通常教导,内存已满的任意数据,它的大块被zero'd出来。虽然的的没放一个空终结者 SRC2 ,有很好的机会 SRC [5] 恰好是 \\ 0 反正。这使得复制成功。注意,这是不会保证,而且可能会失败在任何运行,在任何平台上,在任何时候。不过你很幸运,这一次(也许大部分的时间),和它的工作。

Why does the below C code using strcpy work just fine for me? I tried to make it fail in two ways:

1) I tried strcpy from a string literal into allocated memory that was too small to contain it. It copied the whole thing and didn't complain.

2) I tried strcpy from an array that was not NUL-terminated. The strcpy and the printf worked just fine. I had thought that strcpy copied chars until a NUL was found, but none was present and it still stopped.

Why don't these fail? Am I just getting "lucky" in some way, or am I misunderstanding how this function works? Is it specific to my platform (OS X Lion), or do most modern platforms work this way?

#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;
}

The output from running this code is:

$ ./a.out   
src1: 123456789
dst1: 123456789
src2: hello 
dst2: hello

解决方案

First, copying into an array that is too small:

C has no protection for going past array bounds, so if there is nothing sensitive at dst1[5..9], then you get lucky, and the copy goes into memory that you don't rightfully own, but it doesn't crash either. However, that memory is not safe, because it has not been allocated to your variable. Another variable may well have that memory allocated to it, and later overwrite the data you put in there, corrupting your string later on.

Secondly, copying from an array that is not null-terminated:

Even though we're usually taught that memory is full of arbitrary data, huge chunks of it are zero'd out. Even though you didn't put a null-terminator in src2, chances are good that src[5] happens to be \0 anyway. This makes the copy succeed. Note that this is NOT guaranteed, and could fail on any run, on any platform, at anytime. But you got lucky this time (and probably most of the time), and it worked.

这篇关于为什么会出现这种故意不正确使用的strcpy不可怕的失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆