c - 棘手的指针别名问题

标签 c gcc clang strict-aliasing

以下代码无法编译,因为编译器提示 char** 在调用 PrintStrings()< 时与 const char* const* 不兼容。如果我将 strs 变量声明为 const char**,则对 PrintStrings() 的调用有效,但 memcpy() free() 调用然后提示它们正在获取 const 类型。无论如何,这个问题有吗?请注意,我不想在调用 PrintStrings() 时将 strs 转换为不兼容的类型 const char* const*,因为我正在使用非常激进的编译器优化,这些优化依赖于永不破坏别名规则。

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

[编辑]

请删除此问题中的重复标记。我完全理解为什么 Actor 阵容无效,并且与其他海报不同,这不是我要问的。确实,我的问题和其他问题都围绕相同的编译器问题,但另一个问题是询问编译器为什么首先这样做,而我要求在一个非常具体和棘手的情况下找到解决方法。

最佳答案

更改您的代码,如下所示:

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

关于c - 棘手的指针别名问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24986397/

相关文章:

c - 为什么这个程序中接收输入的两个提示显示在同一行?

c++ - ld : library not found for -lgcc_ext. 10.5

c - 在 C 中使用编写的跳转表或 switch 语句是否更快?

clang - libclang:在 AST 中缺少一些语句?

c - strtok() 跳过第一个标记

C 编程术语

c - 为什么我们将 (temp>>11) 乘以 2 来找到此代码中的第二个

c - 在c编程中将字符串标记为所需长度?

c++ - 使用数组作为元组成员 : Valid C++11 tuple declaration?

c++ - CMake "clang++ is not able compile a simple test program"(软呢帽 20)