realloc,二维分配,泄漏和 valgrind 中的错误

realloc, two dimention allocation, leak and errors in valgrind

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

char** split(const char*, char, int*);
char* substr(const char*, int, int);
void freepath(char**, int);

int main(void) {
    char *str = "home///ubuntu//Desktop";
    char **path = NULL;
    int size = 0;

    path = split(str, '/', &size);

    freepath(path, size);
    return 0;   
}

char** split(const char *str, char c, int *size) {

    char **path = NULL;
    const char *save = str;
    int from=-1, i;

    if(str == NULL)
        return NULL;

    for(i=0 ; 1; ++i) {
        if(*str == '[=10=]') {
            if(from != -1) {
                ++(*size);
                path = (char**)realloc(path, (sizeof(char**) *(*size)));
                *(path+(*size)-1) = substr(save, from, i);
            }
            break;
        }
        if(*str != '/') {
            if(from == -1)
                from = i;
        }
        else {
            if(from != -1) {
                ++(*size);
                path = (char**)realloc(path, (sizeof(char)*(*size)));
                *(path+(*size)-1) = substr(save, from, i);
            }
            from = -1;
        }
        ++str;
    }
    return path;
}

void freepath(char **path, int size) {

    int i=0;

    for(i=0; i<size; ++i) {
        free(*(path+i));
        *(path+i) = NULL;
    }
    free(path);
    path = NULL;
}


char* substr(const char *src, int m, int n)
{
    int len = n - m;
    char *dest = (char*)malloc(sizeof(char) * (len + 1));

    for (int i = m; i < n && (*(src + i) != '[=10=]'); i++)
    {
        *dest = *(src + i);
        ++dest;
    }
    *dest = '[=10=]';

    return dest - len;
}

clang 分析器在您的代码中发现了 4 个可疑点:

1.

char *str = "home///ubuntu//Desktop";

char(指向 const 的指针)前面需要 const

2.

char** split(const char *str, char c, int *size) {

包含未使用的参数 (c)。

3.

path = (char**)realloc(path, (sizeof(char**) *(*size)));

clang-analyser 不喜欢 char** 作为 sizeof 的参数,用 char* 替换它会删除警告。

4.

path = (char**)realloc(path, (sizeof(char)*(*size)));

与 3 相同的警告。错误,不,不一样。答对了!将 sizeof 中的 char 替换为 char*,您就回家了。

最后一点。当你使用 valgrind 时,总是在编译代码中添加调试信息,即在编译器命令行选项(gcc、clang 等)中添加 -g。这将为您提供有关源代码中与 valgrind 发现问题的位置相对应的确切行号的信息。我的程序在 valgrind 下的截图包含的信息比你的多:

请注意,valgrind 正确地将第 44 行识别为存在错误内存分配的行(或第 45 行使用在第 44 行分配的缓冲区存在错误。这两个选项都可能是正确的)。