6
#inlcude <stdio.h>
#inlcude <stdlib.h>
#inlcude <string.h>

int main() {
    char *buff = (char*)malloc(sizeof(char) * 5);
    char *str = "abcdefghijklmnopqrstuvwxyz";

    memcpy (buff, str, strlen(str));

    while(*buff) {
        printf("%c" , *buff++);
    }

    printf("\n");

    return 0;
}

此代码打印整个字符串“abc...xyz”。但是“buff”没有足够的内存来保存该字符串。memcpy() 是如何工作的?它使用 realloc() 吗?

4

4 回答 4

12

您的代码具有未定义的行为。要回答您的问题,NOmemcpy不使用realloc. sizeof(buf)应该足够容纳strlen(str)。少一点就是崩溃。

输出可能会被打印,因为它是一个小程序,但在真正的大代码中,它会导致难以调试的错误。将您的代码更改为,

const char* const str = "abcdefghijklmnopqrstuvwxyz";
char* const buff = (char*)malloc(strlen(str) + 1);

另外,不要这样做,*buff++因为您会丢失内存记录(您分配的内容)。一旦内存使用结束malloc()就应该这样做free(buff),否则就是内存泄漏。

于 2011-05-23T04:45:49.003 回答
9

您可能会打印出整个字符串,但这并不安全,您正在写入和读取未分配的内存。这会产生未定义的行为。

memcpy不做任何内存分配。它只是读取和写入您提供的位置。它不会检查是否可以这样做,在这种情况下,如果您的程序没有崩溃,您就很幸运了。

于 2011-05-23T04:42:15.293 回答
1

memcpy() 是如何工作的?

因为您调用了未定义的行为。未定义的行为可能完全按照您的预期工作,并且可能会做一些完全不同的事情。它甚至可能在同一程序的不同运行之间有所不同。它还可以格式化您的硬盘并且仍然符合标准(当然这不太可能:P)

未定义的行为意味着该行为实际上没有被定义为做任何事情。任何东西都是有效的,包括你看到的行为。请注意,如果您尝试使用free该内存,目标平台的 C 运行时可能会抱怨。;)

于 2011-05-23T04:45:52.533 回答
1

memcpy不使用malloc。正如您所怀疑的那样,您正在注销buff. 在您的简单示例中,这没有明显的危害,但很糟糕。以下是“真实”程序中可能出错的一些事情:

  • 你可能会在buff稍后导致微妙(或不那么微妙)的错误之后在内存中分配的东西上乱涂乱画。
  • 您可能会在mallocand内部使用的标头上乱涂乱画free,从而在您下次调用这些函数时导致崩溃或其他问题。
  • 您最终可能会写入尚未分配给您的进程的地址,在这种情况下您的程序将立即崩溃。(我怀疑这是您所期望的。)

有些malloc实现将未映射的保护页放在分配的内存周围(通常)导致程序在这种情况下崩溃。其他实现会检测到这一点,但仅在您下次调用mallocorfree时(或当您调用特殊函数来检查堆时)。

于 2011-05-23T04:50:23.557 回答