Felix Kreuk
Felix Kreuk

Reputation: 303

Memory leak with dynamic string

so basically my input is a string of an unknown size. what i did is created a function that scans it and allocates memory dynamically for each char.

char* GetUnknownStr(){
char* string = NULL;
char input = 0;
int charCount = 0;
//scan for chars until ENTER is pressed
while (input != '\n'){
    scanf("%c", &input);
    //on last iteration (when ENTER is pressed) break from loop
    if (input == '\n')
        break;
    //realloc new amount of chars
    string = (char*)realloc(string, (++charCount)*sizeof(char));
    //check if realloc didnt fail
    if (string == NULL){
        puts("failed to allocate");
        return 0;
    }
    //assign char scanned into string
    string[charCount-1] = input;
}
//realloc 1 more char for '\0' in the end of string
string = (char*)realloc(string, (++charCount)*sizeof(char)); <--leak
string[charCount-1] = '\0';
return string;
}

VALGRIND:

==30911== HEAP SUMMARY:
==30911==     in use at exit: 4 bytes in 1 blocks
==30911==   total heap usage: 7 allocs, 6 frees, 16 bytes allocated
==30911== 
==30911== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==30911==    at 0x4A05255: realloc (vg_replace_malloc.c:476)
==30911==    by 0x40091F: GetUnknownStr (in /u/stud/krukfel/C/e5/a.out)
==30911==    by 0x40266B: main (in /u/stud/krukfel/C/e5/a.out)
==30911== 
==30911== LEAK SUMMARY:
==30911==    definitely lost: 4 bytes in 1 blocks
==30911==    indirectly lost: 0 bytes in 0 blocks
==30911==      possibly lost: 0 bytes in 0 blocks
==30911==    still reachable: 0 bytes in 0 blocks
==30911==         suppressed: 0 bytes in 0 blocks
==30911== 
==30911== For counts of detected and suppressed errors, rerun with: -v
==30911== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)

for some reason im getting a memory leak, cant figure out why, tried using valgrind but couldnt make too much sense from it. thanks!

Upvotes: 1

Views: 173

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

Apart from minor stylistic issues, such as casting malloc and multiplying by sizeof(char), your code is fine. The actual leak is in the code that calls your function.

A central question in dealing with memory leaks is that of the ownership. Once you know who owns the allocated memory block, you know where it needs to be freed to avoid the leak. In this case, the string is created inside the GetUnknownStr, but then the ownership of that string is transferred to the caller. It is the caller of your GetUnknownStr function who is responsible for calling the free on the result returned from your function. If the caller does not free the string, the leak would be reported. The position of the leak would be the point of last re-allocation, i.e. the line that you marked in your code.

Upvotes: 1

Related Questions