【问题标题】:C - strcpy with malloc size less than argument's size [duplicate]C - malloc 大小小于参数大小的 strcpy [重复]
【发布时间】:2015-06-09 14:16:17
【问题描述】:
char* init_array()
{
    const int size = 5;
    char *p = (char*) malloc(size * sizeof(char));
    strcpy(p, "Hello, world! How are you?");

    return p;
}

如果 size = 5,malloc 应该从内存中获得 5 个空闲字符,但给定的字符串不适合 5 个字符,但它可以工作。

我的问题是为什么?首先我认为结果会被截断,但 p 是完整的字符串,而不仅仅是“Hello”或“Hell\0”

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

【问题讨论】:

  • 你怎么知道它有效?您观察到的是“未定义的行为”。你知道你的代码有问题,但这些错误并不总是导致失败或崩溃,事实上,任何事情都可能发生。
  • 欢迎来到 Stack Overflow!标准警告:Do not cast the result of malloc
  • 只需打印返回指针,使用 printf("%s", init_array());
  • @usrc 然后,阅读这里并正确阅读。请参阅添加的链接@Eregrith。
  • 这称为未定义行为。想想undefined这个词的含义。

标签: c malloc strcpy


【解决方案1】:

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

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

如果您想复制确切数量的字节(比如说 5),您可以使用

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

但请注意,p 在此之后不是有效字符串,因为它没有终止 '\0'

你还有两个新的 c 程序员会做的其他常见的坏习惯

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

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

所以,

p = malloc(size);

应该足以为size - 1 字符串分配空间。

【讨论】:

  • 我在此建议将mistake 替换为bad practice。你会介意的? :-)
  • @NatashaDutta 比脚注好多了...
【解决方案2】:

您遇到的是buffer overflow

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

【讨论】:

    【解决方案3】:

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

    你应该注意,在

    strcpy(str1, str2);  
    

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

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 2012-10-23
      • 2010-11-07
      • 2016-05-07
      • 2014-11-09
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      • 2019-02-09
      相关资源
      最近更新 更多