0

I'm having trouble with freeing memory after allocation using Calloc(), and I get the error free(): invalid next size (fast).
After reading many answers for similar problems I came to a conclusion (or at least, I think), that I don't have enough memory to call free(), and therefore encounter this problem.

Do I allocate enough memory at first place? Is there any thumb rule for allocating? I'm getting kind of lost with that problem.

Here is the part of the code where I try to use free():

void read_mat(mat *matrix, char *str){
    char *p, *q;
    char c;
    int count = 0, i = 0, j = 0, buff = 8, row = 0, col = 0;
    float num;

    p = (char *)calloc(buff, sizeof(char));
    free(p); 
/* ignore the line above, I've tested if I can free that pointer right away, and failed. */

    while (count <= (pow(DIM, 2))){
        c = *(str + i);
        if (c == EOF || c == '\0' || c == ','){
            num = atof(p);
            matrix -> matrix[col][row] = num;
            col++;
            if (col == 4){
                col = 0;
                row++;
            }
            count++;
            i++;
            buff = 8;
            j = 0;
            free(p);
            p = (char *)calloc(buff, sizeof(char));
            if (c == EOF || c == '\0')
                break;
        }
        else if (c == ' '){
            i++;
            continue;
        }
        else {
            p[j] = c;
            i++;
            j++;
            
            if (j == buff - 1){
                buff *= 2;
                q = (char *)realloc(p, buff);
                if (!q){
                    printf("read_mat: Memory allocation failed\n");
                    return;
                }
                p = q;
            }
            
        }
    }
    if (p != NULL)
        free(p);
}
Ben Arviv
  • 3
  • 4
  • *I've tested if I can free that pointer right away, and failed* - what does it mean - failed? Failed how? – Eugene Sh. May 13 '22 at 16:23
  • That actually sounds like some type of memory corruption. Run your program though valgrind or build with address sanitizer turned on. – Stephen Newell May 13 '22 at 16:24
  • if you're getting an error with that initial free, it implies that the heap was already corrupted before you called this function. So some other part of your program probably has a buffer overflow. – Barmar May 13 '22 at 16:25
  • @EugeneSh. : Just played with that - I've allocated memory and tried to free it immediately, and that failed either. – Ben Arviv May 13 '22 at 16:26
  • 1
    Again, what does it mean "failed"? How do you know it? – Eugene Sh. May 13 '22 at 16:27
  • @StephenNewell : I'm pretty new to C, so I am not very familiar with what you've said... I'll dig about it. – Ben Arviv May 13 '22 at 16:29
  • @Barmar: I guess that's possible, I'll chack the rest of the code, thanks. – Ben Arviv May 13 '22 at 16:29
  • @EugeneSh.: I'm getting the same error. – Ben Arviv May 13 '22 at 16:30
  • @EugeneSh. The error message is in the title. – Barmar May 13 '22 at 16:30
  • You aren't making proper checks on the array indexing range, but looping until some calculation result is achieved. For example `row++;`. Trap the value of every indexer, before using it. – Weather Vane May 13 '22 at 16:31
  • @WeatherVane: The variable ```count``` keeps track on the range, or at least thats what it should do. – Ben Arviv May 13 '22 at 16:34
  • Oh, OK. Please post the error message clearly in the question body as well. – Eugene Sh. May 13 '22 at 16:34
  • You `free(p);` in the `while` loop, but don't reset it to `NULL`. So the next `free(p);` at the end of the function will not be harmless. – Weather Vane May 13 '22 at 16:35
  • What I meant, is that there is *no check* on `row` anywhere, and it is used for writing in `matrix -> matrix[col][row] = num;`. If you have strange results, make *no assumptions* about what the code "should do" and make a specific check at the danger points. – Weather Vane May 13 '22 at 16:36
  • @Barmar: Is there any convenient way to search for buffer overflow? I do have other few allocations. – Ben Arviv May 13 '22 at 16:36
  • @BenArviv One of the first comments answered that: Use `valgrind` – Barmar May 13 '22 at 16:37
  • You have `matrix[col][row]` did you intend `matrix[row][col]`? – Weather Vane May 13 '22 at 16:38
  • @WeatherVane I believe I should reset it to ```NULL``` after ```free()```, aren't I? In that case, it doesn't matter because the program exits before freeing the memory... I'll do add a check on ```row```, you're right. About the naming, I indeed need to change that. – Ben Arviv May 13 '22 at 16:44
  • And when you have set it to `NULL` you don't need to check it because `free(NULL)` does nothing. – Weather Vane May 13 '22 at 16:47
  • @WeatherVane But ```p = NULL``` do actually free up the memory that p previously held? – Ben Arviv May 13 '22 at 16:59
  • @Barmar Is ```valgrind``` only available in ```linux```? I use ```windows```, but code in vsc via ```wsl```. – Ben Arviv May 13 '22 at 17:01
  • https://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows – Barmar May 13 '22 at 17:01
  • No, `p = NULL` does not free any memory, it makes the previous memory pointer unavailable. But `free(NULL)` *does nothing*. – Weather Vane May 13 '22 at 17:01
  • @WeatherVane So ```p = NULL``` should be the last line of the code? Do I get it right? – Ben Arviv May 13 '22 at 17:05
  • No. I am saying that you `free(p)` twice. The second time you check if it is `NULL`, but a) you did not set it to `NULL` after the previous `free(p)` and b) there is not need to check it is `NULL` because `free()` is well behaved with a `NULL` pointer (does nothing). You shoud have set `p = NULL` after the *first* `free(NULL);` There is no point doing that as the last line of the function, because `p` is local variable that will no longer be accessible anyway. – Weather Vane May 13 '22 at 17:10
  • @WeatherVane Alright, got it now. Yet, I have to fix that ```free()``` first... – Ben Arviv May 13 '22 at 17:17
  • @Barmar I've used valgrind and indeed had a few memory leaks, but for some reason I can't free one of the pointers and it shows the question's error again. Do you have any idea? – Ben Arviv May 14 '22 at 13:48

0 Answers0