我在释放指针数组中的指针(值)时遇到问题。
typedef struct MyStruct{ char** values; }MyStruct;
在C中,我创建了动态数组。
JSDictionary **array = (JSDictionary **)malloc(sizeof(JSDictionary *) * numRows);
resultSet应该是JSDictionary指针的数组。我创建结构如:
JSDictionary * newJSDictionaryWithSize(unsigned int size)
{
JSDictionary *new = malloc(sizeof(JSDictionary));
printf("new %p\n", self);
new->_size = size;
new->count = 0;
new->values = (char **) malloc(sizeof(char *) * size);
for(unsigned int i = 0; i < size; i++){
new->values[i] = (char *)malloc(sizeof(char *));
}
return new;
}
一切都创造并且运作良好。这是免费的,给我一个问题。
void deallocJSDictionary(struct JSDictionary *self)
{
printf("dealloc %p\n", self);
for(unsigned int i = 0; i < self->_size; i++){
printf("free %p\n", &self->values[i]);
free(self->values[i]);
}
free(self->values);
free(self);
}
我得到一个被释放的指针没有分配错误。传入的指针显示的内存地址与我创建并添加到数组的内存地址相同。值指针(在调试器中)在dealloc函数中显示与创建它时相同的内存地址。问题是试图释放值数组中的第一个点。任何想法为什么值指针数组中的第一个点是不同的?
答案 0 :(得分:4)
到目前为止我看到了两个问题。第一:
new->values[i] = (char *)malloc(sizeof(char *));
此行分配单指针 - 可能不是您想要的。应该是这样的:
new->values[i] = malloc( MAX_SIZE_OF_VALUE );
即。保存值的缓冲区。你也可以分配一个大的chuck来保存所有的值,然后只是偏移到那个内存中。
第二
printf("free %p\n", &self->values[i]);
free(self->values[i]);
这会打印并尝试free(3)
两个不同的指针。首先是第二个地址。
至于实际的释放错误 - 您是否在管理字典的代码中有这样的分配?
dict->values[i] = some_value;
如果是这样的话 - 你正在用指向堆栈或静态内存的指针覆盖指向(和泄漏)已分配内存的指针。您必须将值复制到“值缓冲区”中。类似的东西:
strlcpy( dict->values[i], some_value, MAX_SIZE_OF_VALUE );
希望这有帮助。
答案 1 :(得分:1)
问题可能出在你的内存分配代码中。以下一行
new->values = (char **) malloc(sizeof(char *) * size);
分配一个包含char
元素的size
指针数组。因此,这是不必要的:
for(unsigned int i = 0; i < size; i++){
new->values[i] = (char *)malloc(sizeof(char *));
}
您在这里做的是在char **
数组的每个元素中存储char *
强制转换为new->values
。也就是说,您正在分配足够的内存来存储char *
值,然后在new->values
数组中存储指向该内存的指针。我猜你错误地做了这个,因为
new->values = (char **) malloc(sizeof(char *) * size);
已经为new->values
数组的每个元素分配了足够的内存。
我猜你想要的是:
for(unsigned int i = 0; i < size; i++){
new->values[i] = (char *)malloc(sizeof(char) * MAX_STRING_LENTH);
}
为char
数组的每个元素创建MAX_STRING_LENGTH
个new->values
元素缓冲区。这允许您在每个元素中存储一个字符串,并且您的free
代码应该可以正常工作。
或者,如果new->values
的元素设置在其他地方,那么您可能不希望在解构函数中free
,除非它们是动态分配的,并且您不知道其他引用那时他们就存在了。
答案 2 :(得分:1)
你的功能没有任何内在错误。它们编译得很好,虽然在一些语法错误之后它们按预期产生输出。正如其他人所指出的那样,你可能会分配给已分配的指针,未分配的数据(即堆栈数据),或者你传入的JSDictionary
结构在第一时间没有正确分配通过newJSDictionaryWithSize
。
作为快速测试,只需在JSDictionary
上执行一次alloc / dealloc,即可验证您的功能是否有效。
JSDictionary *ptr = newJSDictionaryWithSize(10);
deallocJSDictionary(ptr);