嵌套在不更新的结构中的联合中的值
Value in a union nested in a struct not updating
我正在用 C 编写 Stack 实现,它允许存储任何数据类型。到目前为止我有这个:
// stack.h
enum ELEMENT_TYPE {
ELEMENT_CHAR,
ELEMENT_INT,
ELEMENT_DOUBLE,
ELEMENT_FLOAT
};
typedef struct {
enum ELEMENT_TYPE type;
union {
char val_c;
int val_i;
double val_d;
float val_f;
};
} Stack_Element;
typedef struct {
unsigned top;
unsigned capacity;
Stack_Element* elements;
} Stack;
Stack* stack_malloc(unsigned capacity) {
Stack* stack = (Stack*)malloc(sizeof(Stack));
stack->top = 0;
stack->capacity = capacity;
stack->elements = (Stack_Element*)malloc(sizeof(stack->elements) * capacity);
return stack;
}
void stack_push(Stack* stack, enum ELEMENT_TYPE type, ...) {
if (isFull(stack)) {
return;
}
va_list ap;
va_start(ap, type);
switch(type) {
case ELEMENT_CHAR:
printf("Pushing char: %c\n", (char) va_arg(ap, int));
stack->elements[stack->top].val_c = (char) va_arg(ap, int); // issue
printf("After pushing: %c\n", stack->elements[stack->top].val_c);
break;
case ELEMENT_INT:
printf("Pushing int: %d\n", va_arg(ap, int));
stack->elements[stack->top].val_i = va_arg(ap, int); // issue
printf("After pushing: %d\n", stack->elements[stack->top].val_i);
break;
case ELEMENT_DOUBLE:
printf("Pushing double: %f\n", va_arg(ap, double));
stack->elements[stack->top].val_d = va_arg(ap, double); // issue
printf("After pushing: %f\n", stack->elements[stack->top].val_d);
break;
case ELEMENT_FLOAT:
printf("Pushing float: %f\n", (float) va_arg(ap, double));
stack->elements[stack->top].val_f = (float) va_arg(ap, double); // issue
printf("After pushing: %f\n", stack->elements[stack->top].val_f);
break;
}
stack->elements[stack->top].type = type;
stack->top++;
va_end(ap);
}
我遇到的问题在 stack->elements[stack->top].val_?
行。在我打印 Pushing X: %x
的第一个 printf
中,值是正确的,所以我会得到类似 Pushing int: 123
.
的内容
但是第二个 printf
的输出是 After pushing: 291176586
,或者另一个垃圾值。我很困惑为什么会这样。感谢任何帮助。
您使用的 va_arg
不正确。手册页说:
每次调用 va_arg() 都会修改 ap 所以
依次返回连续参数的值。
但是你访问了两次。将您的代码更改为:
char tmp = (char) va_arg(ap, int); // Save in tmp variable
printf("Pushing char: %c\n", tmp);
stack->elements[stack->top].val_c = tmp;
printf("After pushing: %c\n", stack->elements[stack->top].val_c);
break;
此外,您的 malloc
是错误的,正如评论中指出的那样。
stack->elements = (Stack_Element*)malloc(sizeof(stack->elements) * capacity);
应
stack->elements = malloc(sizeof(*stack->elements) * capacity);
^
notice
也就是说我更喜欢顺序
stack->elements = malloc(capacity * sizeof *stack->elements);
但它在做同样的事情。
stack->elements = (Stack_Element*)malloc(sizeof(stack->elements) * capacity);
malloc
是错误的,stack->elements
是长度为4的指针。
应该是
stack->elements = (Stack_Element*)malloc(sizeof(Stack_Element) * capacity);
我正在用 C 编写 Stack 实现,它允许存储任何数据类型。到目前为止我有这个:
// stack.h
enum ELEMENT_TYPE {
ELEMENT_CHAR,
ELEMENT_INT,
ELEMENT_DOUBLE,
ELEMENT_FLOAT
};
typedef struct {
enum ELEMENT_TYPE type;
union {
char val_c;
int val_i;
double val_d;
float val_f;
};
} Stack_Element;
typedef struct {
unsigned top;
unsigned capacity;
Stack_Element* elements;
} Stack;
Stack* stack_malloc(unsigned capacity) {
Stack* stack = (Stack*)malloc(sizeof(Stack));
stack->top = 0;
stack->capacity = capacity;
stack->elements = (Stack_Element*)malloc(sizeof(stack->elements) * capacity);
return stack;
}
void stack_push(Stack* stack, enum ELEMENT_TYPE type, ...) {
if (isFull(stack)) {
return;
}
va_list ap;
va_start(ap, type);
switch(type) {
case ELEMENT_CHAR:
printf("Pushing char: %c\n", (char) va_arg(ap, int));
stack->elements[stack->top].val_c = (char) va_arg(ap, int); // issue
printf("After pushing: %c\n", stack->elements[stack->top].val_c);
break;
case ELEMENT_INT:
printf("Pushing int: %d\n", va_arg(ap, int));
stack->elements[stack->top].val_i = va_arg(ap, int); // issue
printf("After pushing: %d\n", stack->elements[stack->top].val_i);
break;
case ELEMENT_DOUBLE:
printf("Pushing double: %f\n", va_arg(ap, double));
stack->elements[stack->top].val_d = va_arg(ap, double); // issue
printf("After pushing: %f\n", stack->elements[stack->top].val_d);
break;
case ELEMENT_FLOAT:
printf("Pushing float: %f\n", (float) va_arg(ap, double));
stack->elements[stack->top].val_f = (float) va_arg(ap, double); // issue
printf("After pushing: %f\n", stack->elements[stack->top].val_f);
break;
}
stack->elements[stack->top].type = type;
stack->top++;
va_end(ap);
}
我遇到的问题在 stack->elements[stack->top].val_?
行。在我打印 Pushing X: %x
的第一个 printf
中,值是正确的,所以我会得到类似 Pushing int: 123
.
但是第二个 printf
的输出是 After pushing: 291176586
,或者另一个垃圾值。我很困惑为什么会这样。感谢任何帮助。
您使用的 va_arg
不正确。手册页说:
每次调用 va_arg() 都会修改 ap 所以 依次返回连续参数的值。
但是你访问了两次。将您的代码更改为:
char tmp = (char) va_arg(ap, int); // Save in tmp variable
printf("Pushing char: %c\n", tmp);
stack->elements[stack->top].val_c = tmp;
printf("After pushing: %c\n", stack->elements[stack->top].val_c);
break;
此外,您的 malloc
是错误的,正如评论中指出的那样。
stack->elements = (Stack_Element*)malloc(sizeof(stack->elements) * capacity);
应
stack->elements = malloc(sizeof(*stack->elements) * capacity);
^
notice
也就是说我更喜欢顺序
stack->elements = malloc(capacity * sizeof *stack->elements);
但它在做同样的事情。
stack->elements = (Stack_Element*)malloc(sizeof(stack->elements) * capacity);
malloc
是错误的,stack->elements
是长度为4的指针。
应该是
stack->elements = (Stack_Element*)malloc(sizeof(Stack_Element) * capacity);