[英]Unexpected C struct pointer size behaviour
我的代码中发生了一些奇怪的行为,这似乎是由于使用通用指针引起的,尽管实际上我完全不确定。 我有一个相当标准的结构,如下所示:
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;
我正在存储指向这些结构元素数组的静态指针,这些数组在堆上分配。 在创建此数组的新元素并将其插入时,其值如下所示...
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-> name的大小和值。 然后,我将此指针存储到哈希表中以供以后检索。 在哈希表中,它存储为简单的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-> name的大小和地址已更改。 更奇怪的是,fe-> name的大小与之前的大小不同,甚至与fe的大小不同。 尝试访问fe-> name给我一个段错误,我不确定如何继续。
当我在具有多个链接库的应用程序中使用代码时,似乎没有兴趣,我确信我正在运行的所有代码都是64位。
我已经在单独的应用程序中成功运行了以上代码,并获得了fe-> name(较小的名称)的正确指针。
我也在64位Ubuntu Linux上运行并使用gcc进行编译。
这确实是我的无知的光芒,尽管正如我想象的那样,它可能有上百万种。 有人可以发光吗?
名称的地址看起来像是内存损坏的结果。 它是完全不对齐的,这对于strdup在堆外返回的地址是不太可能的。
您似乎超出了所创建结构的范围。 您提到它是在堆上创建的,但是在代码中看起来它似乎是在堆栈上创建的。 这不是全部都在同一个函数中完成吗? 在运行下一个块中的代码之前,函数中第一个块中的代码是否存在? 退出该函数后,即使保留指向该结构的指针,该结构的内存也将不再存在。 后来,当您将指针从哈希表中拉出时,内存已被覆盖,并且不再具有在此处命名的指针。 如果您要传递指向结构的指针,请使用malloc动态分配它们。 它们一直存在,直到您使用free(而不是在函数结束时)明确摆脱它们为止。
指针的大小总是相同的,无论它是指向结构的指针还是泛型指针(以前是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
希望能有所帮助。
看起来好像有什么东西正在覆盖该数据结构。 您所看到的指针值0x6e6f74656c656b73
确实看起来非常可疑- "noteleks"
是ASCII,而"skeleton"
向后。 也许这可以使您了解什么将覆盖您的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.