C - malloc 大小小于参数大小的 strcpy

C - strcpy with malloc size less than argument's size

char* init_array()
{
    const int size = 5;
    char *p = (char*) malloc(size * sizeof(char));
    strcpy(p, "Hello, world! How are you?");

    return p;
}

大小为 5 时,malloc 应该从内存中获取 5 个空闲字符,但给定的字符串不适合 5 个字符,但它仍然有效。

我的问题是为什么?首先我认为结果会被截断但 p 是完整的字符串,而不仅仅是 "Hello" 或 "Hell[=18=]"

我在 Linux 上使用 GCC。它与编译器有关还是标准的东西?

它被称为未定义的行为,因为它有时是未定义的。是的,你可以在 c 中写入一个内存块,但这是非法的,因为它会调用未定义的行为,因此该行为是不可预测的,你的程序可能会或可能不会工作。

你对 strcpy() 的期望不会发生,因为 strcpy() 复制了它在 '[=14=]' 终止字节之前找到的尽可能多的字符,它不关心目标缓冲区是否足够大,这是你必须负责的事情。

如果你想复制一个确切的字节数(比方说 5)你可以使用

memcpy(p, "Hello, this string is very large but it doesn't matter", 5);

但请注意 p 之后不是有效字符串,因为它没有终止 '[=14=]'.

你还有 2 个新的 c 程序员常犯的错误做法

  1. 您不需要从 malloc() 转换 return 值。

  2. 您不需要使用 sizeof(char),因为根据定义它是 1。

所以,

p = malloc(size);

应该足以为 size - 1 个字符串分配 space。

您遇到的是buffer overflow

简而言之,您写入无效的内存地址调用 Undefined Behavior。什么事都有可能发生。

它似乎有效,但实际上您的代码调用了未定义的行为。您正在将数据写入未分配的内存位置。

你应该注意到

strcpy(str1, str2);  

strcpy 无法检查 str2 指向的字符串是否适合字符数组 str1。在您的情况下,它将继续将字符从 "Hello, world! How are you? 复制到数组 p 指向的位置。