Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C strdup是一个'\0';复制字符数组时?_C_Strdup - Fatal编程技术网

C strdup是一个'\0';复制字符数组时?

C strdup是一个'\0';复制字符数组时?,c,strdup,C,Strdup,我想知道如果src数组不包含一个'\0',strdup是否会在新数组的末尾添加'\0' 假设我们有一个数组,其中包含由这种malloc分配的“hello” malloc(sizeof(char) * 5); 所以5个字节代表5个字符 我猜src字符串没有收到足够的内存用于“\0” 在这种情况下会发生什么?在这种情况下,strdup()将从传递的字符串开始,然后继续查找内存,直到它从分配内存的末尾脱落(并且您得到一个SIGSEGV或类似值),或者找到一个恰好包含“\0”的字节 它将分配足够的内存

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

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

malloc(sizeof(char) * 5);
所以5个字节代表5个字符

我猜src字符串没有收到足够的内存用于“\0”

在这种情况下会发生什么?

在这种情况下,strdup()将从传递的字符串开始,然后继续查找内存,直到它从分配内存的末尾脱落(并且您得到一个SIGSEGV或类似值),或者找到一个恰好包含“\0”的字节


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

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

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

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

另一个次要注释:如果使用<代码> STRUP ,然后尝试将代码移植到不定义它的编译器中,您可能会考虑编写自己的:

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

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

源字符串怎么可能不包含一个呢?如果您提供的是纯字符串,例如“hello”?是的<代码>“你好”包含一个
\0
。我不知道这一点,但如果你初始化的字符*错误,我的意思是。给他6个字节,给他6个字符。。。差不多吧。我知道编译器会尝试添加一个\0,但它可能会失败。我错了吗?@blastfurny如果您的字符数组不是以null结尾的,那么您就不应该使用“string”这个词。请注意,如果传递给strdup()的字符串是一个编译时常量,例如在strdup中(“这是我的字符串”),那么字符串将以“\0”结尾,这种情况将不适用。