这个 void 指针的转换是有效代码还是恶意代码?

gre*_*ars 2 c casting undefined-behavior

这是有效/正确的代码,还是违反标准——可能会调用未定义的行为(UB)?

void *--> 具体来说,是to char **in的转换foo()。<--

它确实有效,但我们知道“有效”还不够好。

以及任何其他错误,请撕掉它并发布更正的代码(如果您愿意的话)。

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

#define SIZE 5

void foo(void *vp)
{
    char **dp = (char **)vp;
    int i;

    for(i=0; i<SIZE; i++)
    {
        printf("%s", dp[i]);
    }
}

int main()
{
    char **dp;
    int i;

    dp = malloc(SIZE * sizeof(char *));
    for(i=0; i<SIZE; i++)
    {
        dp[i]= malloc(20);
        sprintf(dp[i],"Now: %d\n",i);
    }
    foo(dp);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

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

#define SIZE 5

void foo(void *vp)
{
    char **dp = (char **)vp;
    int i;

    for(i=0; i<SIZE; i++)
    {
        printf("%s", dp[i]);
    }
}

int main()
{
    char **dp;
    int i;

    dp = malloc(SIZE * sizeof(char *));
    for(i=0; i<SIZE; i++)
    {
        dp[i]= malloc(20);
        sprintf(dp[i],"Now: %d\n",i);
    }
    foo(dp);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试过foo(void **vp),这对我来说似乎是正确的,但无法编译。相反,foo(void *vp)似乎是错误的(?),但可以编译并工作。直到现在我才关心这样的琐事,因为我想让我的 C 更上一层楼。

dbu*_*ush 6

Avoid *本质上是一个通用指针类型。任何对象指针类型,无论该指针有多少“级别”,都可以在void *不进行强制转换的情况下来回转换。

因此,从void *到 的转换char **不仅安全,而且不需要强制转换。

尝试使用void **不起作用,因为给予的特殊处理void *不会延续到void **. Avoid **是一种特定类型:指向 a 的指针void *