根据结构内存动态分配C结构和访问成员

时间:2019-05-12 04:00:19

标签: c struct malloc

在C(ANSI)程序中,我有一个结构定义为:

typedef struct Contacts {
    char * name;
    char * email;
    char * phone;
    struct Contacts *next;
} aContact;
aContact *paContact;

根据我要存储的数据长度,是否可以将内存分配为(选项1):

paContact = (struct Contacts *) malloc(sizeof (struct Contacts) +strlen(theName) + strlen(theEmail) + strlen(thePhone) + 3);

,然后执行类似(伪代码)的操作:

paContact->name = paContact;
paContact->email = paContact + strlen(name) + 1;
paContact->phone = paContact->email + strlen(email) + 1;

还是我必须像(选项2)那样为每个成员分别分配内存:

paContact->name = (char*) malloc(sizeof (char)*strlen(name) + 1);
paContact->email = (char*) malloc(sizeof (char)*strlen(email) + 1);
paContact->phone = (char*) malloc(sizeof (char)*strlen(phone) + 1);

如果无法使用选项1,那么跟踪所有分配的内存块以便最终释放它们的正确方法是什么?

谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用任何一种技术。如果在创建结构后可能需要编辑字段,则单独分配可能更合适。如果不需要编辑字段,则一次分配仅需要一次取消分配-并减少了内存碎片。每次分配都有一些开销。

如果您使用单一分配,则需要修正分配。这段代码不会检查内存分配,但是应该。

size_t len_name = strlen(theName);
size_t len_email = strlen(theEmail);
size_t len_phone = strlen(thePhone);
aContact *paContact = malloc(sizeof(*paContact) + len_name + len_email + len_phone + 3);

char *data = (char *)paContact + sizeof(*paContact);
paContact->name = data;
strcpy(paContact->name, theName);
data += len_name + 1;
paContact->email = data;
strcpy(paContact->email, theEmail);
data += len_email + 1;
paContact->phone = data;
strcpy(paContact->phone, thePhone);
paContact->next = NULL;

但是,使用POSIX strdup()可能会更容易:

aContact *paContact = malloc(sizeof(*paContact));
paContact->name  = strdup(theName);
paContact->email = strdup(theEmail);
paContact->phone = strdup(thePhone);
paContact->next  = NULL;

如有必要,您可以很容易地为strdup()编写一个代理:

char *str_dup_surrogate(const char *str)
{
    size_t len = strlen(str) + 1;
    char *result = malloc(len);
    if (result != NULL)
        memmove(result, str, len);
    return result;
}

请注意,名称str_dup_surrogate()避免了在C11 §7.31.13 String handling <string.h>中指定的C库的将来指示。我很想将其缩短为str_dup(),这同样是用户可定义的名称。