0

我的代码中有一些奇怪的行为,这似乎是由于使用了通用指针而导致的,尽管我真的完全不确定。我有一个相当标准的结构,如下所示:

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 指针(一个较小的指针)。

我也在 Ubuntu Linux 64 位上运行并使用 gcc 进行编译。

这确实是我对 C 的无知的地方,尽管我想象它可能是一百万件事。任何人都可以发光吗?

4

3 回答 3

1

name 的地址看起来像是内存损坏的结果。它是完全未对齐的,这对于 strdup 从堆中返回的地址不太可能。

看起来您超出了您创建的结构的范围。您提到它是在堆上创建的,但在代码中它看起来可能是在堆栈上创建的。这不是在同一个函数中完成的,是吗?函数中第一个块中的代码在运行后面块中的代码之前是否已经存在?一旦您退出该函数,该结构的内存就不再存在,即使您保留了指向它的指针。后来,当您将指针从哈希表中拉出时,内存已被覆盖,并且不再有指向名称的指针。如果您要传递指向结构的指针,请使用 malloc 动态分配它们。它们一直存在,直到您使用 free 明确摆脱它们,而不是在函数结束时。

于 2012-04-17T20:33:41.717 回答
0

看起来好像有些东西正在写入该数据结构。0x6e6f74656c656b73您看到的指针值确实看起来非常可疑 - 它是 ASCII 的"noteleks",它是"skeleton"向后的。也许这可能会让您了解什么正在覆盖您的数据。

于 2012-04-17T20:54:51.307 回答
0

Pointers always are of the same size whether its a pointer to a struct or a generic pointer (char * in olden days, void * in ANSI standard.)

Here's a simple example I whipped out so that you could understand structures, pointers (not in detail though but you get the idea.)

#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);
}

Output

sizeof david = 8, sizeof person = 16
sizeof p = 8, sizeof pp = 8
David 40

Hope that helps.

于 2012-04-17T19:48:36.257 回答