复制 char 数组时,strdup 是否添加了“\0”?
Is strdup adding a '\0' when duplicating the array of char?
我想知道如果 src 数组不包含一个,strdup 是否会在新数组的末尾添加一个'\0'?
假设我们有一个数组,其中包含由这种 malloc
分配的 "hello"
malloc(sizeof(char) * 5);
所以 5 个字节对应 5 个字符。
我猜 src 字符串没有为 '\0' 接收到足够的内存。
在这种情况下应该发生什么?
在这种情况下,strdup() 将执行的操作是从传递的字符串开始,然后继续查找内存,直到它脱离已分配内存的末尾(并且您得到 SIGSEGV 或类似信息)或找到一个字节恰好包含 '\0'.
它将分配足够的内存来包含它扫描的所有内容的副本,包括“\0”,然后复制所有内容。
首先是标准免责声明: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
开头的函数。这些都是为实现保留的。因此,即使函数很简单并且其内容的行为也被完美定义,函数作为一个整体的存在仍然给出了未定义的行为。
我想知道如果 src 数组不包含一个,strdup 是否会在新数组的末尾添加一个'\0'?
假设我们有一个数组,其中包含由这种 malloc
分配的 "hello"malloc(sizeof(char) * 5);
所以 5 个字节对应 5 个字符。
我猜 src 字符串没有为 '\0' 接收到足够的内存。
在这种情况下应该发生什么?
在这种情况下,strdup() 将执行的操作是从传递的字符串开始,然后继续查找内存,直到它脱离已分配内存的末尾(并且您得到 SIGSEGV 或类似信息)或找到一个字节恰好包含 '\0'.
它将分配足够的内存来包含它扫描的所有内容的副本,包括“\0”,然后复制所有内容。
首先是标准免责声明: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
开头的函数。这些都是为实现保留的。因此,即使函数很简单并且其内容的行为也被完美定义,函数作为一个整体的存在仍然给出了未定义的行为。