簡體   English   中英

在C中使用char數組深度復制結構(如何復制數組?)

[英]Deep copying structs with char arrays in C (How to copy the arrays?)

我的C程序中有以下結構

struct person {
    char key[50];
    char color[20];
    int age;
};

我想制作一個這個結構的深層副本。 我有深度復制功能設置但是我對如何深度復制字符串有點困惑。 我聽說有人使用strcpy而其他人使用strdup

在我的程序中我想要的是,如果原始人被釋放,深度復制的人的密鑰和顏色不會受到影響。 設置后,鍵和顏色不能改變。 為了我的目的,我應該使用strcpy還是strdup函數?

后K&R(即標准C)你可以分配它們。 下面的函數只是為了使示例清晰,您將始終只是就地分配:

void deepCopyPerson(struct person *target, struct person *src)
{
    *target = *src;
}

詳細說明:char數組是struct對象的一部分(真正的數組,不僅僅是指針!),因此隨對象一起分配和復制。

為了滿足不相信者;-)我在標准草案1570中挖掘:

6.5.16分配操作員

語義

賦值運算符將值存儲在左操作數指定的對象中。 [其次是類型轉換和排序注意事項,與此處無關。]

[...]

6.5.16.1簡單分配

約束

以下其中一項應持有:

  • [...]

  • 左操作數具有與右側類型兼容的結構或聯合類型的原子,限定或非限定版本;

[...]

語義

簡單賦值 (=)中, 右操作數的值將轉換為賦值表達式的類型,並替換存儲在左操作數指定的對象中的值。

要執行包含數組(沒有任何指針)的結構的深層副本,深層副本很簡單

struct person x = {"Key", "Color", 42};   /*  initialise to something */
struct person y = x;

如果“字符串”是指針,這不起作用。 然后有必要分配新的字符串,然后使用strcpy()之類的函數來復制成員。

#include <stdlib.h>
#include <string.h>

struct pointer_person
{
    char *key;
    char *color;
    int age;
};

struct pointer_person deep_copy(struct pointer_person p)
{
     struct pointer_person retval;
     retval.key = malloc(strlen(p.key) + 1);
     strcpy(retval.key, p.key);
     retval.color = malloc(strlen(p.color) + 1);
     strcpy(retval.color, p.color);
     retval.age = p->age;
     return retval;
}

int main()
{
   struct pointer_person p;
   struct pointer_person pc;

   p.key = malloc(50);
   strcpy(p.key, "A key");
   p.color = malloc(20);
   strcpy(p.color, "A colour");
   p.key = 42;

   pc = deep_copy(p);

   /* do stuff with pc and c */

   free(p.key);
   free(p.color);
   free(pc.key);
   free(pc.color);
   return 0;
}

從上面省略了一些錯誤檢查(例如,需要在復制之前檢查malloc()成功)。

如果你使用strcpy()你必須自己分配內存。 strdup()會為你做到這一點。 您可以使用任何一個創建一個與原始內存塊分開的新內存塊,但自然strdup()更簡單,因為它不需要單獨的malloc(strlen())調用。

strcpy()strdup()之間存在差異。

  • strdup()分配空格並返回指向字符串副本的指針,您還必須free()返回的指針。

  • strcpy()獲取分配的空間並將字符串復制到其中。

看起來在你的情況下它是strcpy()因為你的結構的字段不是指針所以你不能為它們分配一個指向分配空間的指針,這是strdup()返回的。

但是,正如本回答中所解釋的那樣,您實際上並不需要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM