释放对象错误

时间:2011-10-27 02:45:22

标签: c arrays string memory-management free

我是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],它也会正确打印出来。

4 个答案:

答案 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;
}

我还可以说这个程序使用的内存永远不会内存:)我不担心。