我是malloc
一串c字符串。释放后,我收到以下错误:
Assembler(87536) malloc: *** error for object 0x108500840: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
为什么?我很确定我正在正确地进行malloc
。我对内存管理很有经验,但我不确定为什么这会给我一个错误。该数组应该包含三个字符串,每个字符串长度为2个字符。
以下是我对数组进行mallocing的方法:
char **reg_store;
reg_store = malloc(3 * (sizeof(char*)));
if (reg_store == NULL) {
fprintf(Out, "Out of memory\n");
exit(1);
}
for (int i = 0; i < 3; i++) {
reg_store[i] = malloc(2 * sizeof(char));
if (reg_store[i] == NULL) {
fprintf(Out, "Out of memory\n");
exit(1);
}
}
以下是我如何释放它:
for (int i = 0; i < 3; i++) {
free(reg_store[i]);
}
free(reg_store);
以下是我的介绍:
// Keeps a reference to which register has been parsed for storage
int count = 0;
char *reg = NULL;
char *inst_ptr // POINTS TO SOME STRING. EXAMPLE: $t2, $t1, $a0
while (1) {
// Parses the string in inst_ptr with dollar, comma and space as a delimiter.
reg = parse_token(inst_ptr, " $,\n", &inst_ptr, NULL);
if (reg == NULL || *reg == '#') {
break;
}
reg_store[count] = reg;
count++;
free(reg);
}
我打电话reg
后打印出来parse_token
并且打印正确。我也打印出reg_store[count]
,它也会正确打印出来。
答案 0 :(得分:1)
我建议添加一些printfs(或使用调试器)来查看所有malloced指针的值,就在它们被malloced之后。然后在它们被释放之前做同样的事情,以确保它们是相同的。也许在程序的其他地方还有一些其他流氓代码在内存上踩踏。
答案 1 :(得分:1)
你的问题出现在“介于两者之间”的代码中,特别是在这里:
reg_store[count] = reg;
count++;
free(reg);
您在设置过程中使用reg_store[count]
分配了malloc
,然后使用reg
覆盖分配的值,然后免费reg
。结果是来自reg_store
中的原始指针的内存泄漏以及reg_store
的每个元素上的双重释放,当您尝试清理所有内容时。
您需要将reg
复制到已在reg_store[count]
中分配的内存中(注意当然的大小),或者不要在“{1}}之前为reg_store
的元素分配任何空间在“代码”之间。
答案 2 :(得分:1)
你的问题在这里:
reg_store[count] = reg;
free(reg);
以后
free(reg_store[i]);
reg已经被释放,你可以再次释放它(不是在谈论以后使用它的问题)。修复此替换
reg_store[count] = reg;
与
strcpy(reg_store[count], reg);
或者根据评论中的建议,因为你知道它的两个字符,最好是memcpy
它:
memcpy(reg_store[count], reg, 2);
答案 3 :(得分:0)
错误已经指出,所以不需要再写一次。 但我可以指出,我不喜欢你处理错误的方式。
void freeRegStore(char** reg_store)
{
int i;
if (reg_store != NULL)
{
for (i = 0; i < 3; i++)
free(reg_store[i]);
free(reg_store);
}
}
char** allocRegStore()
{
int i;
char **reg_store;
reg_store = calloc(3 * (sizeof(char*)), 1);
if (reg_store != NULL)
{
for (i = 0; i < 3; i++)
{
reg_store[i] = malloc(2 * sizeof(char));
if (reg_store[i] == NULL)
{
freeRegStore(reg_store);
return NULL;
}
}
}
return reg_store;
}
在这个方法中,如果没有足够的内存而没有留下碎片,函数allocRegStore将返回NULL。 然后你可以在main中处理这种情况,而不是在分配函数本身。 我不同意使用printf和退出函数。
int main()
{
char** reg_store = allocRegStore();
if (reg_store == NULL)
{
puts("Out of memory");
return 1;
}
... do your stuff
freeRegStore();
return 0;
}
我还可以说这个程序使用的内存永远不会内存:)我不担心。