C:malloc错误 - 要释放的指针未被分配

4
我正在尝试从一个函数返回一个字符串数组,并释放它使用的内存。代码如下:
int main(int argc, const char * argv[])
{
    for (int m = 0; m < 10000; m++) {
        char **data = dataTest();

        int i = 0;
        while(data[i]) {
            printf("%p ",data[i]);
            free(data[i]);
            i++;
        }
        printf(" address= %p.\n",data);
        free(data);
    }

    return 0;
}

以下是函数代码:

char **dataTest()
{
    char *row[] = {"this", "is", "a", "data", "string", NULL};
    char **str = row;
    char **dataReturn = (char **) malloc(sizeof(char *) * 6);

    int i = 0;
    while (*str) {
        dataReturn[i] = malloc(sizeof(char) * strlen(*str));
        strcpy(dataReturn[i++], *str);
        str++;
    }

    return dataReturn;
}

它一开始运行良好,但很快就出现了错误。以下是结果。地址出现了问题,导致了malloc错误。有人遇到过相同的问题吗?
0x100300030 0x100300040 0x100300050 0x100300060 0x100300070  地址 = 0x100300000。
0x100300030 0x100300040 0x100300050 0x100300060 0x100300070  地址 = 0x100300000。
0x100400030 0x100300030 0x100300040 0x100300050 0x100300060  地址 = 0x100400000。
testC(562,0x7fff73e71310)malloc:***错误对象为0 x3000000000000:
释放的指针未分配
***在malloc_error_break中设置断点以进行调试
0x100300060 0x100300070 0x100300030 0x100300040 0x100300050 0x3000000000000                 
程序退出代码:9

1
请查看为什么不要在C语言中对malloc()及其相关函数的返回值进行强制类型转换的原因:https://dev59.com/dHRB5IYBdhLWcg3wgHWr - Sourav Ghosh
3
我认为你只是忘记给 strlen 的结果加上一个空终止符。另外,sizeof(char) 总是不必要的,因为它根据定义始终为 1。 - Fred Larson
1
printf(" address= %p.\n",data); 应该改为 printf(" address= %p.\n",(void *)data);。这是少数几种你实际上应该强制转换指针的情况之一。正如其他人所说:char ** malloc(sizeof(char *) * 6); 应该改为:malloc( sizeof *dataReturn * 6);。这样更容易阅读和理解。 - Elias Van Ootegem
关于为什么printf("%p", (void *) data)需要强制类型转换的完整解释,在标准中是这样写的:_(C11,7.21.6.1p8 格式化输入/输出函数) "p 的参数应该是一个指向 void 的指针。"_ 简而言之,如果在此处没有将void *传递给printf,则会产生未定义行为。 - Elias Van Ootegem
1个回答

8

在您的dataTest函数中,需要在return dataReturn;之前添加以下内容:

dataReturn[i] = NULL ;

否则你的 while (data[i]) {} 将会继续执行,超出预期。
而应该使用如下写法:
dataReturn[i] = malloc( sizeof(char) * (strlen(*str)) );

write:

dataReturn[i] = malloc(strlen(*str) + 1);

为了为终止零分配空间。
顺便说一下,sizeof(char)始终为1。

我认为你的意思是在 free() 循环中使用 while(data[i]) 而不是 while (*str) - Ingo Leonhardt
谢谢,现在它运行得很好。这真的很有帮助!~ - ButterLover
@ButterLover 如果这个回答对您有帮助,请随意接受此答案 - dbush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接