Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
意外的C结构指针大小行为_C_Pointers_64 Bit - Fatal编程技术网

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

意外的C结构指针大小行为,c,pointers,64-bit,C,Pointers,64 Bit,我的代码中出现了一些奇怪的行为,这似乎是由于使用了泛型指针造成的,但实际上我完全不确定。我有一个相当标准的结构,如下所示: 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_en

我的代码中出现了一些奇怪的行为,这似乎是由于使用了泛型指针造成的,但实际上我完全不确定。我有一个相当标准的结构,如下所示:

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会给我一个segfault,我不确定如何继续

出于兴趣,当我在具有多个链接库的应用程序中使用代码时,似乎会发生这种情况,我相当确定我运行的所有代码都是64位的

我已经在一个单独的应用程序中成功地运行了上述代码,并为fe->name(一个较小的)获得了一个正确的指针

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


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

指针的大小总是相同的,无论是指向结构的指针还是通用指针(在过去是char*,在ANSI标准中是void*)

这里有一个简单的例子,我用它来解释结构和指针(虽然不是很详细,但你已经明白了)


希望有帮助。

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


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

看起来似乎有什么东西正在写入该数据结构。您看到的指针值
0x6e6f74656c656b73
看起来确实非常可疑-它是
“noteleks”
的ASCII,即
向后的“骨架”
。也许这可以让您了解是什么在覆盖您的数据。

您可能需要显示分配fe->name的代码。如图所示,它似乎未初始化。地址似乎已更改-0xfe2d40!=0x20049e0。我同意Mark Wilkins的观点-我们需要看到更多的代码(尤其是PyAutoHastable_Get,但是设置名称的代码也是可疑的)。我真的不想发布我的整个hashtable实现,因为它实际上是一堆代码(尽管我已经使用它很长时间了,没有任何问题)。它为fe返回相同的值这一事实使我不那么怀疑它。正如@Harper所说的,0xfe2d40!=0x20049e0。您没有得到相同的结构指针,因此->name不一样也就不足为奇了。0xfe2d40很可能不在func_条目数组的末尾。0x6e6f74656c656b73看起来像字符串的一部分。如果将十六进制值6e 6f 74等解释为ASCII字符,则会得到“notelek”。颠倒顺序,你会得到“骷髅”。因此,func_entries数组可能损坏。指针不必都具有相同的大小。他们倾向于在现代桌面操作系统上安装指针,但对于异国情调的硬件,有一些例子表明一些指针有不同的大小。谢谢你的回答,但这对我的问题没有多大帮助。我对这些基本的东西相当熟悉。事实上,我认为指针有时可能有不同的大小。首先是32位对64位,其次在一些系统中函数指针的大小可能会有所不同:为了澄清我的说法,同一台机器上的指针大小都是相同的。只有在旧的DOS操作系统中,才有近指针和远指针,它们是不同的,但这是非标准的。丹尼尔,编译时有没有收到任何警告?
PyAutoHashtable\u Get
是否返回
func\u条目*
?否则,您需要将其强制转换为
func\u条目*
。然后您可以使用fe_入口本身对结构进行操作。谢谢。骨架当然是经常出现在我的代码库中的字符串。听起来我可能在某个地方有更深层次的记忆衰退。谢谢!我有一种感觉,这并不完全是堆栈问题,但我使用的是realloc,内存的移动使散列中存储的指针无效!丹尼尔,你能澄清一下新职能的范围吗;?如果这是func中的一个局部变量,那么它绝对是指向一个局部释放堆栈变量的全局数组。您需要使用malloc或new调用在堆上分配func_项。
#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