释放对象错误

发布于 2024-12-11 20:58:56 字数 1398 浏览 0 评论 0原文

我正在 malloc 一个 C 字符串数组。释放它后,出现以下错误:

Assembler(87536) malloc: *** error for object 0x108500840:pointer being freed was not allocate *** 在malloc_error_break中设置断点来调试

这是为什么呢?我非常确定我正确执行了 malloc 操作。我在内存管理方面非常有经验,但我不确定为什么这会给我一个错误。该数组应包含三个字符串,每个字符串长 2 个字符。

这是我如何分配数组:

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);
}

在调用 parse_token 后,我打印出 reg 并且它确实打印正确。我还打印了 reg_store[count] 并且它也打印正确。

I am mallocing an array of c strings. After releasing it, I get the following error:

Assembler(87536) malloc: *** error for object 0x108500840: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

Why is that? I am pretty sure I am doing the malloc correctly. I'm pretty experienced with memory management, but I am not sure why this is giving me an error. The array is should hold three strings, each of which is 2 characters long.

Here is how I am mallocing the array:

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);
    }
}

Here is how I am freeing it:

for (int i = 0; i < 3; i++) {
    free(reg_store[i]);
}
free(reg_store);

Here is what I have in between:

// 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);
}

I am printing out reg after I call parse_token and it does print out correctly. I am also printing out reg_store[count] and it does also print out correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼趣 2024-12-18 20:58:56

你的问题就在这里:

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);

Your problem is here:

reg_store[count] = reg;
free(reg);

and later

free(reg_store[i]);

reg is already freed and you free it another time (not talking about the problems with using it later). to fix this replace

reg_store[count] = reg;

with

strcpy(reg_store[count], reg);

or as suggested in the comments, since you know its two charaters, its better to memcpy it:

memcpy(reg_store[count], reg, 2);
高冷爸爸 2024-12-18 20:58:56

我建议添加一些 printfs (或使用调试器)来查看所有 malloc 指针在 malloc 后的值。然后在它们被释放之前做同样的事情,以确保它们是相同的。也许程序中的其他地方还有一些其他恶意代码正在破坏内存。

I would suggest adding some printfs (or use the debugger) to see the values of all the malloced pointers just after they have been malloced. Then do the same just before they are freed, to make sure they are the same. Perhaps there is some other rogue code elsewhere in the program that is stomping over memory.

带刺的爱情 2024-12-18 20:58:56

您的问题出在“中间”代码中,特别是在这里:

reg_store[count] = reg;
count++;
free(reg);

您在设置期间使用 malloc 分配了 reg_store[count] ,然后覆盖分配的值使用reg,然后释放reg。结果是,当您尝试清理所有内容时,reg_store 中的原始指针发生内存泄漏,并且对 reg_store 的每个元素进行双重释放。

您需要将 reg 复制到 reg_store[count] 中已分配的内存中(当然要注意大小),或者不为 的元素分配任何空间reg_store 在“中间”代码之前。

Your problem is in the "in between" code, in particular, right here:

reg_store[count] = reg;
count++;
free(reg);

You allocated reg_store[count] with malloc during your set up, then you overwrite the allocated value with reg and then free reg. The result is a memory leak from the original pointers that were in reg_store and a double-free on each element of reg_store when you try to clean everything up.

You need to copy reg into the memory already allocated in reg_store[count] (watching the size of course) or don't allocate any space for the elements of reg_store before the "in between" code at all.

茶花眉 2024-12-18 20:58:56

错误已经指出了,不用再写了。
不过,我可以指出,我不喜欢您处理错误的方式。

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 和 exit 。

int main()
{
    char** reg_store = allocRegStore();

    if (reg_store == NULL)
    {
        puts("Out of memory");
        return 1;
    }

    ... do your stuff

    freeRegStore();
    return 0;
}

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

The error was already pointed out so no need to write it again.
I can however point out that i don't like the way you are handling errors.

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

In this method, the function allocRegStore will return NULL if there was not enough memory without leaving pieces around.
Then you can handle this case in main and not in the allocation function itself.
I disagree with the use of printf and exit inside functions.

int main()
{
    char** reg_store = allocRegStore();

    if (reg_store == NULL)
    {
        puts("Out of memory");
        return 1;
    }

    ... do your stuff

    freeRegStore();
    return 0;
}

I can also say that the memory used by this program will never go out of memory :) i would not worry about that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文