C:结构体的 union 和 union 作为函数中参数的复杂使用会产生未定义的行为

标签 c function pointers struct unions

我目前正在尝试开发一个小规模程序来模拟使用 union 作为参数的方法,然后再使用相同的想法开发更大规模的程序。 union 由两个结构组成。

在我的程序中,第一个结构体有一个 unsigned int,第二个结构体有 81 个元素的 char 数组。下面的 union 具有两种类型的成员结构。接下来是函数 ufuncx(); 的原型(prototype),它有两个参数: union 指针和 int。

我正在尝试实现一种方法,在该方法中我可以将 union 指针传递给函数,该 union 指针指向 union 外部定义的两个结构地址之一,这也是 union 结构成员的一部分。

源代码列表:

/*
   this is a program test to see if different types of union members can `enter code as
   function arguments of the same union type.
*/

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

struct id_num
{
   unsigned short int idnumber;
};

struct namedisc
{
   char name[81];
};

union combo_x
{
   struct id_num numtest;
   struct namedisc note;
};

int ufuncx(union combo_x *, int);

int main(void)
{

//step 1:

    union combo_x *a, *b;

    //struct data

    struct namedisc text;
    struct id_num age;

//step 2a:

    //pointer *a - uses the id_num struct

    age.idnumber = 25;
    a->numtest = age;

//step 2b:

    //pointer *b - uses the namedisc struct

    strcpy(text.name,"John Doe\0");
    b->note = text;

//step 3:

      /*=- if you comment this, a pointer error in run time occurs -=*/
      printf(".... %s\n",b->note.name);

//step 4:

    //show output

    ufuncx(a,1);
    ufuncx(b,2);

    return 0;
}

int ufuncx(union combo_x *data,int part)
{

    if(part < 1 || part > 2)
    {
        printf("we dont have that part...\n");
        return -1;
    }

    if(part == 1)
    {
        printf(" age = %d ",data->numtest.idnumber);
    }

    if(part == 2)
    {
        printf("name = %s ",data->note.name);
    }

    printf("(it works!)\n");

    return 0;
}

这是此源代码的运行时输出:

.... John Doe
 age = 25 (it works!) 
name = John Doe (it works!)

这看起来不错,而且似乎可以工作,但是有一个问题。 在我的程序的第 3 步中,如果我注释掉 printf(); 语句,我会得到:

 age = 25 (it works!)
name = (null) (it works!)
!$h *tl J#@^&

name = (null)(它有效!),在此更改中后跟随机垃圾,表示错误的指针地址。

注释掉的 printf(); 语句不应在运行时产生影响,但在本例中却会产生影响。我的第一个想法是,我遇到了指针问题,特别是当我尝试使用间接运算符将结构文本的地址分配给指针 b 时。

我看不出步骤 2b 出了什么问题。我尝试以多种方式重新设计它,但出现编译器错误。这就是我陷入困境的地方 - 因为我遇到了逻辑错误。

基于此程序思想的更大规模模型将有两个由许多结构体作为成员组成的 union 体,因为每个结构体将有许多不同数据类型的成员(即短整型、字符数组等),这些成员将被传递作为函数的参数。相同的目标,只是扩展。

提前致谢。

最佳答案

如果你的编译器没有对你发出尖叫,那么你要么没有打开足够的警告选项,要么你需要一个更好的编译器。您不能将 union 成员(指向)传递给 union 体成员,就好像它是 union 体的一部分一样;除非您忽略编译器发出的警告,否则不允许您作弊 - 这几乎总是一个坏主意。

请注意,您的指针 ab 尚未初始化,因此取消引用它们会立即导致未定义的行为 - 如果幸运的话,则会出现核心转储,谁知道会发生什么如果你运气不好的话。

union combo_x *a, *b;
struct namedisc text;
struct id_num age;

age.idnumber = 25;
a->numtest = age;   // a is uninitialized - undefined behaviour

strcpy(text.name,"John Doe\0");
b->note = text;     // b is uninitialized - undefined behaviour

您可能会想到:

struct namedisc text;
struct id_num age;   
union combo_x *a = (union combo_x *)&text;
union combo_x *b = (union combo_x *)&age;

a->numtest.idnumber = age;
strcpy(b->note.name, "John Doe");

但是强制转换对于阻止编译器合理的提示是必要的。

您可以合法地做的是:

union combo_x a;
union combo_x b;

a.numtest.idnumber = age;
strcpy(b.note.name, "John Doe");

关于C:结构体的 union 和 union 作为函数中参数的复杂使用会产生未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8425155/

相关文章:

c - 从文件读取时获取结构中的垃圾值

C exit 表现得像 return 吗?

C : Unidentified if evaluation issue

pointers - 转到 : doubly linked list implementing panic error

c - 表达式 c=a+++b 的输出是什么?如果c语言中a=2,b=5...?

c - 项目帮助 : Function and Struct issues in C?

c++ - std::function 的问题

function - Haskell 运行时错误 : error: Prelude. (!!):索引太大

c - 为什么这个工作 : Array of pointers to C strings?

c++ - 语法 `const char (&x)[]` 的含义