Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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_Memory Management_Pool - Fatal编程技术网

C 指向结构的指针:理解元素寻址

C 指向结构的指针:理解元素寻址,c,pointers,memory-management,pool,C,Pointers,Memory Management,Pool,所以我有这个结构: typedef struct my_structure_s{ uint32_t* label; uint32_t* data_1; uint32_t* data_2; } my_structure_t; 最终,我将致力于分配单个大内存块,并移动指针指向大内存块中的适当位置。这个块将足够大,以便我可以为数据_1和数据_2的N1和N2元素留出空间,其中N1和N2在程序中计算 实际上,我将有一些这样的结构,我想最终把它们都指向这个街区的适当位置。我知道如何

所以我有这个结构:

typedef struct my_structure_s{
    uint32_t* label;
    uint32_t* data_1;
    uint32_t* data_2;
} my_structure_t;
最终,我将致力于分配单个大内存块,并移动指针指向大内存块中的适当位置。这个块将足够大,以便我可以为数据_1和数据_2的N1和N2元素留出空间,其中N1和N2在程序中计算

实际上,我将有一些这样的结构,我想最终把它们都指向这个街区的适当位置。我知道如何将指针移动到正确的位置,但我很难理解内存中的内部指针是在哪里创建的

例如,我定义:

my_structure_t* my_struct = malloc( sizeof(my_struct) );
my_structure_t example_struct;
my_struct = &example_struct;
现在我想看看相对地址,所以我写:

printf("Base Address: %p\n", &my_struct);
printf("First Element: %p\n", &(my_struct->label));
printf("Difference: %x\n\n", (uint32_t)&(my_struct->label) - (uint32_t)&my_struct);
由于某种原因,差异是负值!为什么?是的,我使用的是32位内核。第一个元素不应该在堆的旁边,而是更靠下的地方吗?另外,为什么内存差异不是0x4而是-0x8?我认为所有的东西都应该对齐…看看它是一个相同数据类型的重复结构…并且该数据类型的sizeof()为4

第二,如果我没有将指针指向结构的实例,该怎么办?如果我这样做怎么办:

my_structure_t* my_struct_2;
my_structure_t* big_pool =  malloc( sizeof(my_structure_t) );
my_struct_2 = big_pool;    

printf("Base Address: %p\n", &my_struct_2);
printf("First Element: %p\n", &(my_struct_2->label));
printf("Difference: %x\n",  (uint32_t)&(my_struct_2->label) - (uint32_t)&my_struct_2);
在这里,值是完全古怪的。有一次,我得到了0x49f02aac的差值。那么,实际的标签指针放在内存中的什么位置?在这种情况下,如何确保标签指针本身的地址正好位于基址之后,而不将基址指针指向普通结构实例?它能以某种方式分配吗

也就是说,如果我在创建结构指针之后将标签指针指向某个地方,那么标签指针本身将存储在哪里?如何确保所有这些内部指针都存储在基指针之后,与定义中的顺序相同

是的,是的,我可以定义data_1[MAX_N1]或其他类似的工作,然后定义一个结构指针数组,并为每个指针分配一个固定的内存大小,但我没有。原因是多方面的。请坚持我要问的问题


谢谢

我的结构
是指向
我的结构
的指针。对于指针相对于它指向的对象的位置没有任何保证

根据您对内存位置的评论,我相信您正在尝试测试什么

printf("Base Address: %p\n", my_struct);
printf("First Element: %p\n", &(my_struct->label));
printf("Difference: %x\n\n", (uint32_t)&(my_struct->label) - (uint32_t)my_struct)
请注意,与您的代码相比,在
my_struct
之前的两个位置删除了
&

回答你提出的实际问题

另外,为什么内存差异不是0x4而是-0x8

要么
sizeof(my_structure\u t*)
是8,要么编译器决定
example_struct
应该是8字节对齐的,并在向堆栈添加变量时添加了填充。

首先,
malloc()
不分配指针,它为结构分配内存,然后返回指向它的指针。完全可能有一个未初始化的指针,或者指针不指向任何地方(
NULL

第二,在C中,关于分配有三种类型的变量:

  • 静态变量(全局变量)。它们在程序运行时始终存在
  • 自动变量(局部变量)。只要包含它们的代码块正在运行,它们就存在
  • 动态变量(malloc)。他们存在,直到他们被释放
  • 记住你的例子:

    my_structure_t* my_struct = malloc( sizeof(my_struct) );
    my_structure_t example_struct;
    my_struct = &example_struct;
    
    第一种结构是动态的,第二种结构是自动的。然后让指针指向自动指针。记住,你可以有指向任何东西的指针。动态变量丢失(泄漏)

    这很棘手:
    my_struct
    是一个指针,但是您得到的是它的地址,所以您得到的是类型为pointer的自动变量
    my_struct
    的地址

    出现-8是因为您正在比较两个局部变量的地址:局部指针
    my_struct
    和局部结构变量
    example_struct
    的成员
    label
    。而这些恰好是内存中的布局

    请尝试:

    printf("Base Address: %p\n", (void*)my_struct);
    printf("First Element: %p\n", (void*)&(my_struct->label));
    
    (顺便说一句:当
    printf(“%p”)
    时,转换到
    (void*)
    总是一个好主意


    另一个例子有一个类似的错误:打印结构的地址或指针的值,但不打印指针的地址。

    旁注:从内存地址转换到
    uint32\t
    是一个坏主意,尤其是在64位系统下,这会使代码不可移植。巴拉克——是的,我知道,但我只是这样做试着去理解事物。
    printf("Base Address: %p\n", (void*)my_struct);
    printf("First Element: %p\n", (void*)&(my_struct->label));