krystah
krystah

Reputation: 3733

realloc() seems to affect already allocated memory

I am experiencing an issue where the invocation of realloc seems to modify the contents of another string, keyfile.

It's supposed to run through a null-terminated char* (keyfile), which contains just above 500 characters. The problem, however, is that the reallocation I perform in the while-loop seems to modify the contents of the keyfile.

I tried removing the dynamic reallocation with realloc and instead initialize the pointers in the for-loop with a size of 200*sizeof(int) instead. The problem remains, the keyfile string is modified during the (re)allocation of memory, and I have no idea why. I have confirmed this by printing the keyfile-string before and after both the malloc and realloc statements.

Note: The keyfile only contains the characters a-z, no digits, spaces, linebreaks or uppercase. Only a text of 26, lowercase letters.

int **getCharMap(const char *keyfile) {

    char *alphabet = "abcdefghijklmnopqrstuvwxyz";
    int **charmap = malloc(26*sizeof(int));

    for (int i = 0; i < 26; i++) {
        charmap[(int) alphabet[i]]    = malloc(sizeof(int)); 
        charmap[(int) alphabet[i]][0] = 0; // place a counter at index 0
    }


    int letter;
    int count = 0;
    unsigned char c = keyfile[count];
    while (c != '\0') {
        int arr_count = charmap[c][0]; 
        arr_count++; 

        charmap[c] = realloc(charmap[c], (arr_count+1)*sizeof(int));

        charmap[c][0] = arr_count; 
        charmap[c][arr_count] = count; 

        c = keyfile[++count];  
    }



    // Just inspecting the results for debugging        
    printf("\nCHARMAP\n");
    for (int i = 0; i < 26; i++) {
        letter = (int) alphabet[i];
        printf("%c: ", (char) letter);
        int count = charmap[letter][0];

        printf("%d", charmap[letter][0]);
        if (count > 0) {
            for (int j = 1; j < count+1; j++) {
                printf(",%d", charmap[letter][j]);
            }
        }
        printf("\n");
    }
    exit(0);

    return charmap;
}

Upvotes: 0

Views: 111

Answers (2)

barak manos
barak manos

Reputation: 30136

The following piece of code is a source of troubles:

int **charmap = malloc(26*sizeof(int));
for (int i = 0; i < 26; i++)
    charmap[...] = ...;

If sizeof(int) < sizeof(int*), then it will be performing illegal memory access operations.

For example, on 64-bit platforms, the case is usually sizeof(int) == 4 < 8 == sizeof(int*).

Under that scenario, by writing into charmap[13...25], you will be accessing unallocated memory.


Change this:

int **charmap = malloc(26*sizeof(int));

To this:

int **charmap = malloc(26*sizeof(int*));

Upvotes: 1

Graham Borland
Graham Borland

Reputation: 60681

charmap[(int) alphabet[i]]    = malloc(sizeof(int)); 
charmap[(int) alphabet[i]][0] = 0; // place a counter at index 0

You are writing beyond the end of your charmap array. So, you are invoking undefined behaviour and it's not surprising that you are seeing weird effects.

You are using the character codes as an index into the array, but they do not start at 0! They start at whatever the ASCII code for a is.

You should use alphabet[i] - 'a' as your array index.

Upvotes: 6

Related Questions