返回指向指针数组的指针

时间:2010-07-03 21:02:22

标签: c pointers arrays

我在释放指针数组中的指针(值)时遇到问题。

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函数中显示与创建它时相同的内存地址。问题是试图释放值数组中的第一个点。任何想法为什么值指针数组中的第一个点是不同的?

3 个答案:

答案 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_LENGTHnew->values元素缓冲区。这允许您在每个元素中存储一个字符串,并且您的free代码应该可以正常工作。

或者,如果new->values的元素设置在其他地方,那么您可能不希望在解构函数中free,除非它们是动态分配的,并且您不知道其他引用那时他们就存在了。

答案 2 :(得分:1)

你的功能没有任何内在错误。它们编译得很好,虽然在一些语法错误之后它们按预期产生输出。正如其他人所指出的那样,你可能会分配给已分配的指针,未分配的数据(即堆栈数据),或者你传入的JSDictionary结构在第一时间没有正确分配通过newJSDictionaryWithSize

作为快速测试,只需在JSDictionary上执行一次alloc / dealloc,即可验证您的功能是否有效。

JSDictionary *ptr = newJSDictionaryWithSize(10);
deallocJSDictionary(ptr);