nevzatseferoglu
nevzatseferoglu

Reputation: 1186

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 == '\0') {
            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) != '\0'); i++)
    {
        *dest = *(src + i);
        ++dest;
    }
    *dest = '\0';

    return dest - len;
}

Upvotes: 0

Views: 63

Answers (1)

zkoza
zkoza

Reputation: 2861

clang analyser has found 4 suspected points in your code:

1.

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

needs const in front of char (pointer to const).

2.

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

contains an unused parameter (c).

3.

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

clang-analyser does not like char** as the argument of sizeof, replacing it with char* removes the warning.

4.

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

The same warning as in 3. Errr, no, not the same. Bingo! Replace char inside sizeof with char* and you're back home.

One final remark. When you use valgrind, always add debugging information to the compiled code, that is, add -g to the compiler command-line options (gcc, clang, etc.). This will give you the information about the exact lines numbers in your source code corresponding to the places where the problem was spotted by valgrind. My screenshot of your program under valgrind contains more information than yours:

screenshot of valgrind

Please notice that valgrind correctly identifies line 44 as the line with the buggy memory allocation (or line 45 with a buggy usage of the buffer allocated at line 44. Both options are a priori possibly correct).

Upvotes: 1

Related Questions