在 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 不可行,那么跟踪所有分配的内存以便我最终可以释放它们的正确方法是什么?
谢谢!
最佳答案
您可以使用任一技术。如果您可能需要在创建结构后编辑字段,那么单独的分配可能更合适。如果不需要编辑字段,则一次分配只需要一次释放 - 并且还减少了内存碎片。每次分配都有一些开销。
如果您使用单一分配,则需要修复分配。此代码不检查内存分配,但应该检查。
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 库的 future 方向。我很想将其缩短为 str_dup()
,这同样是用户可定义的名称。
关于c - 根据结构体内存动态分配C结构体和访问成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56096119/