为什么标准中有“strdup”函数,而没有“memdup”函数?

问题描述 投票:0回答:6

在 C 中,您可以使用

strdup
来简洁地分配缓冲区并将字符串复制到其中。然而,据我所知,一般记忆没有类似的功能。例如,我不能说

struct myStruct *foo = malloc(sizeof(struct myStruct));
fill_myStruct(foo);

struct myStruct *bar = memdup(foo, sizeof(struct myStruct));
// bar is now a reference to a new, appropriately sized block of memory,
//   the contents of which are the same as the contents of foo

那么,我的问题有三个:

  1. 是否有一些像这样的我不知道的标准库函数?
  2. 如果没有,是否有一种简洁且最好是标准的方法来执行此操作,而无需显式调用
    malloc
    memcpy
  3. 为什么 C 包含
    strdup
    但不包含
    memdup
c memcpy strdup c-standard-library
6个回答
19
投票

你可以用一个简单的函数来实现它:

void* memdup(const void* mem, size_t size) { 
   void* out = malloc(size);

   if(out != NULL)
       memcpy(out, mem, size);

   return out;
}

7
投票

GNU Gnulib 的

void *xmemdup (void const *p, size_t s)
中有
xalloc.h

请注意,如果内存不足,它会调用

xalloc_die


0
投票

您可能只想自己定义

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 标准都包含许多便利函数,但不幸的是没有这个。

示例:使用

strdup()
重新实现
memdup()

char *strdup(const char *src)
{
    return memdup(src, strlen(src) + 1);
}

示例:使用

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;
}

0
投票

为什么 C 包含

strdup
但不包含
memdup

在 C23 之前,

strdup
不是 C 标准库函数。但它是一个 POSIX 函数。您可以注意到在 动态内存 TR 之前的模式,除了存在分配内存的函数之外,没有任何东西返回指向动态分配的内存缓冲区的指针,您可以稍后调用
free
(getdelim、getline 、strdup、strndup - 这些都不是标准函数)。我不知道这个设计选择背后的原因,但我猜
memdup
也因为同样的原因而没有实现。

是否有一些像这样的我不知道的标准库函数?

没有。

如果没有,是否有一种简洁且最好是标准的方法来执行此操作,而无需显式调用

malloc
memcpy

没有。


-2
投票

strdup 函数读取并复制以 null 结尾的字符串,直到 null。但是,普通数据没有任何此类分隔符,因此您需要为其指定要复制的数据的长度。


-6
投票

复制任意内存结构并不像复制字符串那么简单。例如,当结构包含指向其他结构(例如字符串)的指针时,您应该如何处理? “复制”这样的结构意味着什么?与字符串的情况不同,这个问题没有一个正确的答案。在这种情况下,最好让应用程序开发人员创建一种根据其用例制作结构副本的机制,而不是通过假装有规范的方法来处理它来混淆问题。

© www.soinside.com 2019 - 2024. All rights reserved.