繁体   English   中英

意外的C结构指针大小行为

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM