';memdup';C语言中的函数?
在C语言中,您可以使用';memdup';C语言中的函数?,c,memcpy,strdup,C,Memcpy,Strdup,在C语言中,您可以使用strdup简洁地分配缓冲区并将字符串复制到其中。然而,据我所知,一般记忆没有类似的功能。例如,我不能说 struct myStruct*foo=malloc(sizeof(struct myStruct)); 填写我的结构(foo); struct myStruct*bar=memdup(foo,sizeof(struct myStruct)); //bar现在是一个新的、大小合适的内存块的引用, //其内容与foo的内容相同 那么,我的问题有三个: 有没有像这样的标准
strdup
简洁地分配缓冲区并将字符串复制到其中。然而,据我所知,一般记忆没有类似的功能。例如,我不能说
struct myStruct*foo=malloc(sizeof(struct myStruct));
填写我的结构(foo);
struct myStruct*bar=memdup(foo,sizeof(struct myStruct));
//bar现在是一个新的、大小合适的内存块的引用,
//其内容与foo的内容相同
那么,我的问题有三个:
malloc
和memcpy
strdup
而不包含memdup
复制任意内存结构并不像复制字符串那样简单。例如,当结构包含指向其他结构(如字符串)的指针时,应该如何处理?“复制”这样的结构意味着什么?与string的情况不同,没有一个正确的答案。在这种情况下,最好让应用程序开发人员根据他们的用例创建一种复制结构的机制,而不是假装有一种规范的方法来处理它,从而混淆问题。strdup函数在以null结尾的字符串上读取并复制null。但是,普通数据没有任何此类分隔符,因此您需要为其指定要复制的数据长度。您可以通过一个简单的函数来实现它:
void* memdup(const void* mem, size_t size) {
void* out = malloc(size);
if(out != NULL)
memcpy(out, mem, size);
return out;
}
您可能只想自己定义
memdup()
,然后按照前面的建议在代码中使用它。我的函数版本如下
void *memdup(const void *src, size_t n)
{
void *dest;
dest = malloc(n);
if (dest == NULL)
return NULL;
return memcpy(dest, src, n);
}
至于讨论memdup()
是否太琐碎甚至多余,我不这么认为。它对于在代码中复制结构非常有用。C标准库的ANSI/ISO和POSIX标准都包含许多方便的函数,但不幸的是,这不是一个
示例:使用memdup()
重新实现strdup()
示例:使用memdup()
复制对象
int some_function(const struct some_struct *some_const_data)
{
struct some_struct *my_mutable_copy;
my_mutable_copy = memdup(some_const_data, sizeof *some_const_data);
if (my_mutable_copy == NULL)
return -1;
...
return 0;
}
GNU Gnulib的
xalloc.h
中有void*xmemdup(void const*p,size\t s)
请注意,如果内存不足,它会调用
xalloc\u die
。不会strdup
只是一个malloc
和一个memcpy
?这是两个函数调用。(malloc()
和memcpy()
)似乎太琐碎了,不值得为其创建函数<如果您想避免对字符串进行过多的传递,则代码>strdup()会稍微复杂一些。@Mystical:strdup()的哪个实现不需要对输入字符串进行两次传递?(一次调整缓冲区大小,一次复制)我的目的主要是为了代码可读性——我想从struct myStruct*bar=(struct myStruct*)malloc(sizeof(struct myStruct));memcpy(bar、foo、sizeof(struct-myStruct))“代码>到一个相对较短的行,在那里可以清楚地看到发生了什么。@Dan不要抛出malloc
的结果。”。除此之外,C不包括strdup
。不过,POSIX确实如此,所以它的应用非常广泛。但你不能指望它是可用的。和struct myStruct*bar=malloc(sizeof*bar)*bar=*foo代码>看起来还不错,是吗?有memcpy(),memcmp(),memmemmem(),memchr()。正如前面所指出的,void*memdup(const void*mem,size\u t size)
?与memcpy()的工作方式相同。它的意思是复制一个内存区域,这个内存区域碰巧是一个数据结构。除非memdup不是结构的副本。根据名称,它将复制一个内存区域。这是memdup,不是datastructuredup。@Tim Ring:。。。同样的问题也适用于普通赋值。低级别memdup
无法正确复制结构这一事实不能有意义地用作反对memdup
的论点。这个答案只是一个煽动性的尝试,试图用不必要的噪音来填补这个问题。@AnT:如果每次我看到这种试图在StackOverflow的行为时都能得到一美元就好了……这是正确的答案。strdup存在的原因不仅仅是将两个调用包装成一个调用,而是因为扫描空字节的逻辑,因为执行malloc+strcpy将导致冗余strlen。这对于memdup是不需要的,这就是为什么当一个简单的malloc+memcpy就足够了时,它不是特别合理的原因。@rdb memdup和memcpy一样,可以接受一个大小参数。我觉得这不是一个令人信服的答案。@rdb是的,strdup
将三个调用包装成一个调用,strlen
调用肯定不是多余的-您需要以某种方式确定字符串的长度(或所需的内存量)。通常,在复制字符串之前需要分配内存,在这种情况下,基本上需要调用strlen
,malloc
和strcpy
按顺序排列。strlen
+malloc
+memcpy
可能更有效。这并不能回答三个具体问题中的任何一个questions@Hooper好,实际上,NUL字节是从以NUL结尾的src字符串复制而来的。这是唯一一个实际回答任何问题的响应。
int some_function(const struct some_struct *some_const_data)
{
struct some_struct *my_mutable_copy;
my_mutable_copy = memdup(some_const_data, sizeof *some_const_data);
if (my_mutable_copy == NULL)
return -1;
...
return 0;
}