14

在 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. 如果没有,是否有一种简洁且最好是标准的方法来执行此操作而无需显式调用mallocand memcpy
  3. 为什么 C 包含strdup但不包含memdup
4

5 回答 5

18

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

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

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

   return out;
}
于 2015-03-13T14:52:56.687 回答
6

void *xmemdup (void const *p, size_t s)GNU Gnulib 的xalloc.h.

请注意,它会xalloc_die在内存不足的情况下调用。

于 2019-08-13T08:08:20.710 回答
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()using 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;
}
于 2018-01-16T12:41:49.960 回答
-2

strdup 函数读取并复制空终止字符串上的空值。但是,普通数据没有任何此类分隔符,因此您需要为其指定要复制的数据的长度。

于 2012-12-01T20:59:23.457 回答
-6

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

于 2012-12-01T20:58:46.557 回答