Search code examples
cwinapicharmallocfree

C array char* completly free memory during execution


im looking to understand why this script dont completly free his memory allocation. The windows memory used chart drop just a little from these about 400Mb total allocated. All the memory are free with an array of int, but not with an array of char*

How to do it right ? many thanks for your help...

void testAlloc() {
unsigned char error = 0;
char **arr;
char **buf;
size_t size = 1;
size_t idx = 0;
size_t nextIdx;
size_t newSize;

arr = calloc(size, sizeof(char*));

while(idx < 9999999) {
    nextIdx = idx+1;
    newSize = nextIdx*2;
    if(nextIdx > size) {
        buf = realloc(arr, newSize * sizeof(char*));
        if(buf != NULL) {
            arr = buf;
            size = newSize;
            }else{
                error = 1;
                }
        }
    if(!error) {
        arr[idx] = calloc(32, sizeof(char));
        arr[idx] = "sample text";
        }
    idx++;
    }

MessageBox(NULL, "stop before free", "", MB_OK);

size_t i = 0;
if(!error && arr != NULL) {
    while(i < idx) {
        free(arr[i]);
        i++;
        }
    free(arr);
    arr = NULL;
    }
}
testAlloc();

Solution

  • Here:

            arr[idx] = calloc(32, sizeof(char));
            arr[idx] = "sample text";
    

    You are allocating 32 bytes of memory and storing a pointer to them in arr[idx], then you are overwriting that pointer with a pointer to the array represented by the string literal. The dynamic allocation is leaked. Furthermore, you invoke undefined behavior later when you attempt to free the space pointed to by the array element, because the pointer then stored in the array was not obtained from any of the allocation functions.

    Presumably, you wanted to copy the contents of the string into the allocated space, instead of overwriting the pointer to the space. For that, you want strcpy().

            arr[idx] = calloc(32, sizeof(char));
            // Note: an error check really ought to be performed here
            strcpy(arr[idx], "sample text");