我有一个像这样的动态结构:
struct network {
int count;
char** ips;
}
如果我知道每个字符串数组都是16个字节(即INET_ADDRSTRLEN
)因为它们是IPv4地址,那么如果我使用sizeof(char*) * count
或sizeof(char) * INET_ADDRSTRLEN * count
进行分配是否重要?
例如:
// n is a pointer to a network
n->ips = realloc(n->ips, sizeof(char*) * n->count);
for (int i =0; i< n->count; i++){
n->ips[i] = malloc(INET_ADDRSTRLEN);
strcpy(n->ips[i], "127.0.0.1");
}
OR
n->ips = realloc(n->ips, sizeof(char) * INET_ADDRSTRLEN * n->count);
for (int i =0; i< n->count; i++){
n->ips[i] = malloc(INET_ADDRSTRLEN);
strcpy(n->ips[i], "127.0.0.1");
}
另外,如果我是第二种方式,我是否需要n->ips[i] = malloc(INET_ADDRSTRLEN);
?
答案 0 :(得分:3)
ips指向char *数组,因此其缓冲区必须是sizeof(char *)的倍数,而不是sizeof(char)的倍数。
答案 1 :(得分:1)
为了获得可靠性,最好使用malloc
/ realloc
的惯用形式:
n->ips = malloc(n->count * sizeof(*n->ips))); // n * sizeof(element)
这样,如果ips
的类型某天会发生变化,那么在每次出现内存分配函数时都不需要修改代码。
根据经验,总是检查内存分配函数的结果,因为它可能会失败。
答案 2 :(得分:0)
在你的代码中,ips是指向char的指针。因此,当您为它分配内存时,您需要为指向char的指针分配空间。这意味着您的第一个示例是正确的。
脚注:我假设你在其他地方有代码将ips初始化为NULL值。对随机垃圾进行realloc
是一个坏主意。如果这不是实际的重新分配,请考虑使用malloc
。如果这是一个真正的重新分配,那么你有一个内存泄漏,因为数组中的计数指针正在被新缓冲区替换,而不会释放先前的缓冲区。
最后,我认为您需要malloc INET_ADDRSTRLEN + 1来为尾随空字符保留空间。