我的代码中有一些奇怪的行为似乎是由于使用通用指针而导致的,但实际上我完全不确定。我有一个相当标准的结构,如下所示:
typedef struct {
char* name;
PyAutoCFunc ac_func;
void (*func)();
PyAutoType type_id;
int num_args;
PyAutoType arg_types[MAX_ARG_NUM];
} func_entry;
static func_entry* func_entries;
我正在存储一个静态指针,指向在堆上分配的这些struct元素的数组。在我创建此数组的新元素并插入它的位置,它的值看起来像这样......
func_entry new_fe;
new_fe.name = malloc(strlen(name) + 1);
strcpy(new_fe.name, name);
... // Init rest of struct
func_entries[num_func_entries] = new_fe;
num_func_entries++;
func_entry* fe = &func_entries[num_func_entries-1];
printf("Setting function '%s' at address '%p', name address '%p'\n", name, fe, fe->name);
输出。
>>> Setting function 'graphics_viewport_set_title' at address '0xfe2d40', name address '0xe40fe0'
注意fe->名称的大小和值。然后我将此指针存储到哈希表中以便稍后检索。在哈希表中,它存储为一个简单的void *。后来当我从哈希表中检索指针时,发生了一件奇怪的事情。
func_entry* fe = PyAutoHashtable_Get(func_table, c_func_name);
printf("Getting function '%s' at address '%p', name address '%p'\n", c_func_name, fe, fe->name);
哪个输出。
>>> Getting function 'graphics_viewport_set_title' at address '0xfe2d40', name address '0x6e6f74656c656b73'
fe的地址显然已经进出散列表而没有问题,但是fe->名称的大小和地址已经改变。更奇怪的是,fe->名称与之前的名称大小不同,甚至与fe的大小不同。试图访问fe->名称会给我一个段错误,我不确定如何继续。
当我在具有多个链接库的应用程序中使用代码时,似乎会出现这种情况,我很确定我运行的所有代码都是64位。
我已在一个单独的应用程序中成功运行上述代码,并为fe-> name(一个较小的一个)获取正确的指针。
我也在Ubuntu Linux 64位上运行并使用gcc进行编译。
这真的是我的C无知闪耀的地方,因为我想它可能是一百万件事。任何人都能发光吗?
答案 0 :(得分:1)
名称的地址看起来像内存损坏的结果。它完全没有对齐,这对于strdup从堆返回的地址不太可能。
您的创建结构似乎超出了范围。你提到它是在堆上创建的,但在代码中看起来它可能是在堆栈上创建的。这并不都是在同一个功能中完成的,是吗?在运行后一个块中的代码之前,函数中第一个块中的代码是否存在?一旦退出该函数,该结构的内存就不再存在,即使您保留了指向它的指针。之后,当您将指针从哈希表中拉出时,内存已被覆盖,并且没有指向其名称的指针。如果您要传递指向结构的指针,请使用malloc动态分配它们。它们存在,直到您使用free明确地删除它们,而不是在函数结束时。
答案 1 :(得分:0)
指针始终具有相同的大小,无论它是指向结构的指针还是通用指针(旧时为char *,ANSI标准中为void *。)
这是一个简单的例子,我掏出来让你能理解结构,指针(虽然不是很详细,但你明白了。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {
char *name;
int age;
};
void print(void *);
int main()
{
struct person *david;
if ((david = (struct person *)malloc(sizeof(struct person))) != NULL) {
david->name = strdup("David");
david->age = 40;
printf("sizeof david = %d, sizeof person = %d\n", sizeof david,
sizeof(struct person));
print((void *)david);
}
}
void print(void *p)
{
struct person *pp = (struct person *)p;
printf("sizeof p = %d, sizeof pp = %d\n%s %d\n", sizeof p, sizeof pp,
pp->name, pp->age);
}
<强>输出
sizeof david = 8, sizeof person = 16
sizeof p = 8, sizeof pp = 8
David 40
希望有所帮助。
答案 2 :(得分:0)
看起来好像在写一些数据结构。您看到的指针值0x6e6f74656c656b73
看起来确实非常可疑 - 它是"noteleks"
的ASCII,向后"skeleton"
。也许这可能会让你知道什么是覆盖你的数据。