【发布时间】:2011-08-07 11:16:00
【问题描述】:
我今天一直在玩 C,而我从来没有机会玩过的东西,那就是使用带有指向函数的指针的结构......一切都很顺利,直到我开始遇到一些奇怪的错误,当我正在清理整个东西(顺便说一句:我在 x86_64 架构中编译,在 Mac 中)
看了又看,我发现这是内存对齐,在 node_vtable 结构中。
在 i386 中,它工作正常..没有任何问题。但是,正如我在 x86_64 中所说,它不起作用。
/* NOT WORKING */
struct node_vtable {
void (*add_node) (linked_list *, node *);
node * (*create_node) (linked_list *, float, int, int );
void (*print) (linked_list *llist);
};
/* WORKING */
struct node_vtable {
void (*print) (linked_list *llist);
void (*add_node) (linked_list *, node *);
node * (*create_node) (linked_list *, float, int, int );
};
现在,我修复了将指针node * (*create_node) (linked_list *, float, int, int ); 移动到结构末尾的问题,因为该指针的大小为 24 字节,这是该结构中最大的。但是,我真的认为肯定有一个更优雅的解决方案,而且我正在寻找一个明确的解释。因此,如果有人可以给出提示或解释,那就太好了;) ....因为我的大脑现在真的卡住了:)
整个代码:
#include <stdio.h>
#include <stdlib.h>
struct node {
int id;
int var;
float f_var;
struct node *next;
};
typedef struct node node;
typedef struct linked_list linked_list;
/* Structs */
struct node_vtable {
void (*add_node) (linked_list *, node *);
node * (*create_node) (linked_list *, float, int, int );
void (*print) (linked_list *llist);
};
struct linked_list {
/************************/
node *head;
node *tail;
/************************/
node *data;
/* VTable to Methods*/
struct node_vtable *method;
};
/*Prototypes*/
linked_list *constructor_linked_list();
void print(linked_list *llist);
void add_node(linked_list *this, node *node);
node *create_node(linked_list *this, float f_var, int var, int _id);
/***************/
linked_list *constructor_linked_list() {
printf("calling constructor_linked_list...\n");
linked_list *this = (linked_list *)malloc(sizeof(linked_list));
this->head = NULL;
this->tail = NULL;
this->method = NULL;
this->method = (struct node_vtable *)malloc(sizeof(struct node_vtable *));
this->method->print = &print;
this->method->add_node = &add_node;
this->method->create_node = &create_node;
return this;
}
void print(linked_list *llist) {
printf("calling print ...\n");
node *iter = llist->head;
while (iter){
printf("\tnode %d\n", iter->id);
iter = iter->next;
}
}
void add_node(linked_list *this, node *node) {
printf("calling add_node_...\n");
if (this->head == NULL) {
node->next = NULL;
this->head = node;
this->tail = node;
} else {
node->next = NULL;
this->tail->next = node;
this->tail = node;
}
}
node *create_node(linked_list *this, float f_var, int var, int _id) {
printf("calling create_node ...%d\n",(int)sizeof(struct node_vtable));
node *ret_node = (node *)malloc(sizeof(struct node));
ret_node->var = var;
ret_node->id = _id;
ret_node->f_var = f_var;
ret_node->next = NULL;
return ret_node;
}
int main(int argc, char *argv[]) {
linked_list *obj = constructor_linked_list();
int i;
for (i = 0; i < 10; i++) {
obj->method->add_node(obj, create_node(obj, 5.0, 3, i));
}
obj->method->print(obj);
return EXIT_SUCCESS;
}
干杯
【问题讨论】:
-
你能展示你如何分配/初始化/使用/释放这些结构吗?成员的顺序不应该改变任何东西 - 你可能在其他地方有错误。
-
它以什么方式“不起作用”。你得到什么样的错误?
-
我收到一个程序接收信号:“EXC_BAD_ACCESS”。
标签: c struct memory-alignment