free():在 tcache 2 中检测到双释放 已中止

free(): double free detected in tcache 2 Aborted

提问人:Abelrahman hussein Ragab 提问时间:10/16/2023 最后编辑:Steve FriedlAbelrahman hussein Ragab 更新时间:10/17/2023 访问量:93

问:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void ffree(char **pp)
{
    if (!pp)
        return;

    char **a = pp;

    while (*pp) {
        free(*pp);  // Free the memory pointed to by pp
        pp++;       // Move to the next pointer
    }

    free(a); // Finally, free the memory for the array of pointers
}

int main() {
    char *str1 = strdup("Hello");
    char *str2 = strdup("World");
    
    char *arr[] = {str1, str2};

    ffree(arr);

    return 0;
}

在上面的简单代码片段中,我正在编写自己的字符串数组自由函数,其中释放指向字符串数组的指针

我的代码有问题吗?

c 指针 dynamic-memory-allocation free

评论


答:

4赞 Lundin 10/16/2023 #1

错误 1:

char *arr[] = {str1, str2};此处数组末尾没有 NULL 指针哨兵值。

因此,这没有任何意义:

  while (*pp) {
    free(*pp);  // Free the memory pointed to by pp
    pp++;       // Move to the next pointer

错误 2:

free(a);这从未动态分配过,因此不应释放。

评论

0赞 Abelrahman hussein Ragab 10/17/2023
我现在看到我的代码的问题是数组不是动态分配的,并且其末尾没有附加 NULL 值。谢谢大家的帮助^^
-1赞 فِرجِيل 10/16/2023 #2

程序中存在几个错误:

首先,您需要知道,您只能释放动态分配的内存(例如通过),在代码中使用哪些调用。malloc()strdup()malloc()

char *arr[] = {str1, str2};不是动态分配的,你不能释放它。

其次,在 C 语言中,二维字符数组由 .因此,以下代码块不起作用,因为在 arr 中没有 NULL:NULL

while (*pp) {
    free(*pp);
    pp++;
}

要使其正常工作,您需要将 添加到数组的最后一行:NULL

char *arr[] = {str1, str2, NULL};

此外,该函数可能会失败,您需要系统地检查它是否不返回 NULL,存在段错误的风险,因此您应该执行以下操作:malloc()

char *str1, *str2;

if ((str1 = strdup("Hello") == NULL) {
    // Error handling
}

if ((str2 = strdup("World") == NULL) {
    // Error handling
}

下面是代码的更正版本:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void ffree(char **pp)
{
    if (!pp)
        return;

    size_t i = 0;

    while (pp[i]) {
        free(pp[i]);
        i++;
    }

    free(pp);
}

int main(void) {

    char *str1 = strdup("Hello");
    char *str2 = strdup("World");

   if (!str1 || !str2) {
        if (str1) {
            free(str1);
        }
        if (str2) {
            free(str2);
        }
        return (-1)
   }

    char **arr = malloc(3 * sizeof(char *));

    if (!arr) {
        free(str1);
        free(str2);
        return (-1);
    }

    arr[0] = str1;
    arr[1] = str2;
    arr[2] = NULL;

    ffree(arr);

    return (0);
}

评论

0赞 Jabberwocky 10/16/2023
“其次,在 C 语言中,二维字符数组由 NULL 分隔。 ”:这种说法是错误的。
0赞 فِرجِيل 10/16/2023
@Jabberwocky 按照惯例,而且在其代码中,它的工作方式是这样的。
0赞 Jabberwocky 10/16/2023
而且你更正的代码太复杂了......
1赞 chux - Reinstate Monica 10/17/2023
@VirgilG。提示:不需要空指针测试。 可以简化为可以。if (str1) { free(str1); }free(str1);free(0)
1赞 Abelrahman hussein Ragab 10/17/2023
我现在看到我的代码的问题是数组不是动态分配的,并且其末尾没有附加 NULL 值。谢谢大家的帮助^^