【问题标题】:Is strdup adding a '\0' when duplicating the array of char? [closed]复制char数组时strdup是否添加了'\ 0'? [关闭]
【发布时间】:2015-06-22 04:27:33
【问题描述】:

我想知道如果 src 数组不包含一个,strdup 是否会在新数组的末尾添加一个 '\0' ?

假设我们有一个包含由这种 malloc 分配的“hello”的数组

malloc(sizeof(char) * 5);

所以 5 个字节对应 5 个字符。

我猜 src 字符串没有为 '\0' 接收到足够的内存。

在这种情况下应该发生什么?

【问题讨论】:

  • 源字符串怎么能不包含一个?
  • 如果你给出一个纯字符串,例如“hello”?
  • 是的。 "hello" 包含一个 \0
  • 我不知道,但如果你初始化错误你的 char*,我的意思是。将他分配 6 个字节并给他 6 个字符......类似的东西。我知道编译器会尝试添加一个 \0 但它可能会失败我错了吗?
  • @Blastfurnace 如果您的 char 数组不是以空字符结尾的,那么您不应该使用“字符串”这个词。

标签: c strdup


【解决方案1】:

在这种情况下,strdup() 会做的是从传递的字符串开始,然后继续查看内存,直到它从分配的内存结束(并且你得到一个 SIGSEGV 或类似的)或者找到一个发生的字节包含一个 '\0'。

它将分配足够的内存来包含它扫描的所有内容的副本,包括“\0”,然后复制所有内容。

【讨论】:

  • 请注意,如果传递给 strdup() 的字符串是例如编译时间常数,如 strdup("This is my string"),字符串 以 '\0 结尾,这种情况不适用。
【解决方案2】:

首先是标准免责声明:strdup 不是标准化函数,因此它的确切作用可能(至少在理论上)因编译器而异。也就是说,我看到的每个实现都以相同的方式工作。

strdup 将确定输入字符串的长度——它将从您传递的指针中的地址开始,并在该位置之后找到第一个 NUL 字节。然后它会分配一个新的内存块并将该范围内的字节复制到新分配的块中。

所以会发生两件事之一。输入将包含零字节,结果也将包含零字节,否则strdup 将读取您传递的输入的末尾,您将获得未定义的行为(但很有可能它会找到零字节,并将一堆额外的垃圾复制到重复的字符串中)。

另一个小注意事项:如果您使用strdup,然后尝试将您的代码移植到未定义它的编译器,您可能会考虑编写自己的代码:

char *strdup(char const *s) { 
    size_t len = strlen(s) + 1;
    char *ret = malloc(len);
    if (ret != NULL)
        strcpy(ret, s);
    return ret;
}

这显然是一件很容易做到的事情,但它还有另一个问题:将它包含在代码中会产生未定义的行为。您不能编写名称以str 开头的函数。这些都是为实现而保留的。因此,即使该函数很简单,并且其内容的行为已被完美定义,但仅作为一个整体存在的函数仍然会产生未定义的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-27
    • 2014-08-13
    • 2013-04-14
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多