Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么要从从void初始化的结构中获取垃圾值**_C_Pointers_Memory Management_Data Structures - Fatal编程技术网

C 为什么要从从void初始化的结构中获取垃圾值**

C 为什么要从从void初始化的结构中获取垃圾值**,c,pointers,memory-management,data-structures,C,Pointers,Memory Management,Data Structures,我测试这段代码: void foo (void* data[]) { static struct structure { char character; int integer; } st1 = *((struct structure *)data); printf("[%i][%c]", st1.integer, st1.character); } int main (void) { void* *data = ca

我测试这段代码:

void foo (void* data[])
{
    static struct structure
    {
        char character;
        int  integer;
    } st1 = *((struct structure *)data);

    printf("[%i][%c]", st1.integer, st1.character);
}

int main (void)
{
    void* *data = calloc(2, sizeof(void* ));
    char  arg1 = 'b';
    int   arg2 = 20;

    data[0] = (char* )&arg1;
    data[1] = (int* ) &arg2;

    foo(data);

    return(0);
}
但我得到的是垃圾值,而不是预期值

[20] [乙]


我尝试过很多东西,包括st1=
*((struct structure*)和data)
,(尽管AFAIK
data
已经是一个地址)声明并初始化单独的结构指针,然后将其解除引用,但没有任何效果


发生这种情况的原因是什么?我应该如何正确地接近获取函数参数的相同想法?

通常,可移植的情况下,您不能期望您的结构与两个
void*
的大小相同

不能期望在结构本身内部有任何特定的填充。当内存区域被重新解释为结构的一部分时,您不能期望将
char
强制转换为
void*
将产生相同的有效
char

(我想我读过的代码)的行为是无法定义的



我最初完全忽略了这样一个事实,即您将地址分配给两个
void*
(假设您将
char
int
本身转换为
void*
),因此您对这些值的重新解释根本不需要产生您所期望的结果。事实上,它可能会导致陷阱值。因此,您的代码是未定义的行为。

您的问题在于您的结构本身

在您的
数据
中,您在main中编写了一个
int*
和一个
char*
。但是,在函数中,您定义结构,因为它包含
char
int
,您应该编写以下内容:

void foo (void* data[])
{
    static struct structure
    {
        char* character;
        int*  integer;
    } st1 = *((struct structure *)data);

    printf("[%i][%c]", *(st1.integer), *(st1.character));
}

这闻起来像UB,但你把参数的顺序搞混了。@StoryTeller很抱歉,这似乎是写博文的错,因为我既不能也不能复制/粘贴。原始代码具有适当的顺序。问题仍然存在。当我看到一个空指针时,我想——一个人在想什么——设计和编码是错误的。大错特错。修复设计和代码,使其不使用void。您的代码在多个级别上未定义。没有合理的方法“修复”此问题。
void*
在无法假定类型时使用,也无所谓。你的代码想要假设,这对它来说非常重要。结构的大小是8字节,void**的大小是12字节。两个void*将是24@Malina-除了计算错误之外,除了
char
之外,对于任何数据类型,您都不能期望任何特定的
sizeof
。你不需要假设,使你的代码不被定义。我只是告诉你sizeof的结果。我没有做任何计算。你能告诉我做这件事的正确方法吗?因此,我可以完成对“过于宽泛的问题”使用堆栈溢出的操作。
sizeof(void**)==2
并不意味着
2*sizeof(void*)==24
。这两种类型不需要大小相同。即使这些是结果。您是否认为您的结构完全位于您传递的内存的前8个字节内有问题?@Malina-正确的方法是避免这堆未定义的行为。除了
无符号字符*
之外,不要处理任何原始内存。使用
memcpy
memove
并实际服用药物,从代码库中删除该黑客行为。