棘手的指针别名问题

时间:2014-07-27 22:46:07

标签: c gcc clang strict-aliasing

以下代码无法编译,因为编译器在调用char**时抱怨const char* const*PrintStrings()不兼容。如果我将strs变量声明为const char**,则对PrintStrings()的调用有效,但memcpy()free()调用会抱怨他们正在获取const类型。反正这个问题呢?请注意,我不想在调用strs时将const char* const*强制转换为incompatbiele类型PrintStrings(),因为我正在使用依赖于永不破坏别名规则的非常激进的编译器优化。

#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;
}

[编辑]

请从此问题中删除重复的标记。我完全理解为什么演员表是无效的,而不像其他海报不是我要问的。确实,我的问题和其他问题都围绕着相同的编译器问题,但另一个问题是询问编译器为什么会这样做,而我要求在一个非常具体和棘手的情况下解决方法。

1 个答案:

答案 0 :(得分:2)

更改您的代码,使其如下:

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++]);