fieldtensor
fieldtensor

Reputation: 4050

Tricky pointer aliasing issue

The following code fails to compile because the compiler complains about char** being incompatible with const char* const* in the call to PrintStrings(). If I declare the strs variable as const char**, then the call to PrintStrings() works, but the memcpy() and free() calls then complain that they are getting const types. Is there anyway around this issue? Note that I don't want to cast strs to the incompatbiele type const char* const* in the call to PrintStrings(), because I'm using very aggressive compiler optimizations that rely on never breaking aliasing rules.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
PrintStrings(const char* const* strs)
{
    int x = 0;
    while(strs[x])
        printf("%s", strs[x++]);
}

int
main(void)
{
    int x = 0;

    /* If I make this "const char**" then the memcpy's and free's will fail,
     * but if I leave the const off then the call to PrintString() fails */

    char** strs = malloc(5 * sizeof(char*));

    strs[0] = malloc(128);
    memcpy(strs[0], "Hello", 1 + strlen("Hello"));

    strs[1] = malloc(128);
    memcpy(strs[1], " ", 1 + strlen(" "));

    strs[2] = malloc(128);
    memcpy(strs[2], "World!", 1 + strlen("World!"));

    strs[3] = malloc(128);
    memcpy(strs[3], "\n", 1 + strlen("\n"));

    strs[4] = NULL;

    PrintStrings(strs);

    while(strs[x])
        free(strs[x++]);
    free(strs);

    return 0;
}

[EDIT]

Please remove the duplicate marker from this question. I fully understand why the cast is invalid, and unlike the other poster that's not what I'm asking about. It's true that both my question and that other question center around the same compiler issue, but the other question is asking about why the compiler does that in the first place, whereas I'm asking for a workaround in a very specific and tricky case.

Upvotes: 2

Views: 122

Answers (1)

Ross Ridge
Ross Ridge

Reputation: 39651

Change your code so it's like this:

char const **strs = malloc(sizeof(char*) * 5);
char *s;

strs[0] = s = malloc(128);
memcpy(s, "Hello", 1 + strlen("Hello"));

strs[1] = s = malloc(128);
memcpy(s, " ", 1 + strlen(" "));

...

while(strs[x])
    free((char *) strs[x++]);

Upvotes: 2

Related Questions