【问题标题】:'strcpy' with 'malloc'?'strcpy' 和'malloc'?
【发布时间】:2011-07-18 07:36:06
【问题描述】:

执行以下操作是否安全?

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

int main(void)
{
    char* msg;

    strcpy(msg, "Hello World!!!");  //<---------

    printf("%s\n", msg);

    return 0;
}

还是应该使用下面的?

char* msg = (char*)malloc(sizeof(char) * 15);

【问题讨论】:

  • 你需要 malloc,否则 msg 只是一个悬空指针。
  • 使用malloc,但删除演员表和sizeof(char)。正确用法是char *msg = malloc(15);
  • 另外malloc() 是在&lt;stdlib.h&gt; 而不是&lt;malloc.h&gt; 中声明的
  • 并且应该始终检查来自malloc()的返回值:char *msg = malloc(15); if (msg == NULL) /* not ok to proceed */;
  • @MateuszPiotrowski:如果你不检查,你就无法知道它是否“有效”。返回 NULL 是 malloc 告诉您出现问题的方式。

标签: c malloc strcpy


【解决方案1】:

用途:

#define MYSTRDUP(str,lit) strcpy(str = malloc(strlen(lit)+1), lit)

现在它变得简单且符合标准:

char *s;
MYSTRDUP(s, "foo bar");

【讨论】:

  • malloc失败的情况除外
  • 缺少 (char*) 演员表 #define MYSTRDUP(str,lit) strcpy(str = (char*)malloc(strlen(lit)+1), lit)
【解决方案2】:

您的原始代码未分配味精。尝试 strcpy 会很糟糕。您需要在 strcpy 进入之前分配一些空间。您可以按照建议使用 malloc 或在堆栈上分配空间,如下所示:

char msg[15];

如果你 malloc 内存,你应该记得在某个时候释放它。如果您在堆栈上分配,则内存将在超出范围时自动返回到堆栈(例如函数退出)。在这两种情况下,您都需要小心分配足够的空间,以便能够将最长的字符串复制到其中。你可能想看看 strncpy 以避免数组溢出。

【讨论】:

  • 如果 msg 的大小小于字符串的长度,说 "char msg[3]; strcpy(msg, "abcdefg");",可以吗?如果现在,我 cout msg,输出会是“abcdefg”吗?
  • 不,不会。 char msg[3] 为 3 个字符分配空间。您不能将 8 个字符复制到该空格中(7 个字母加上一个空终止符)。
【解决方案3】:
 char* msg;
 strcpy(msg, "Hello World!!!");  //<---------Ewwwww
 printf("%s\n", msg); 

这是 UB。没有第二个想法。 msg 是一个野指针,尝试取消引用它可能会导致您的实现出现段错误。

msg 指向一个足够大的有效内存位置以容纳"Hello World".

试试

char* msg = malloc(15);
strcpy(msg, "Hello World!!!");

char msg[20]; 
strcpy(msg, "Hello World!!!");

【讨论】:

  • (UB == 未定义行为)
【解决方案4】:

第一个版本不安全。而且,msg 应该指向“Hello World!!!”的有效内存位置被复制。

char* msg = (char*)malloc(sizeof(char) * 15);
strcpy(msg, "Hello World!!!");

【讨论】:

  • 不要转换malloc的返回值,也不要使用sizof(char)
  • 为什么不 sizeof(char)?
  • char 在 c 中保证为 1 个字节
  • @yampelo 所以sizeof(char) 既正确又清晰但多余。不用说“不要使用”
【解决方案5】:

strdup 为你做 malloc 和 strcpy

char *msg = strdup("hello world");

【讨论】:

  • strdup 不是 C 标准,不是 C89 也不是 C99
  • POSIX 是一个标准。我们使用的很多东西不是 C89 或 C99。这不是不使用如此简单的东西的理由。请在编写像 MYSTRDUP() 这样的密集宏之前使用 strdup。 strdup 需要 1 行作为函数来实现,坦率地说,应该在标准中。
  • 当然可以,但值得一提的是,这是在 POSIX 中。
  • strdup 出现了奇怪的问题,但只在 Win 10 上,malloc+strcpy 才有效?!
  • 我会非常怀疑诸如“strdup 出现奇怪问题”之类的说法。
【解决方案6】:

您需要分配空间。在strcpy 之前使用malloc

【讨论】:

    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 2013-05-30
    • 2015-09-17
    • 2013-11-12
    • 2016-01-25
    • 1970-01-01
    • 2014-10-04
    • 2017-11-21
    相关资源
    最近更新 更多