所以我有这个结构:
typedef struct my_structure_s{
uint32_t* label;
uint32_t* data_1;
uint32_t* data_2;
} my_structure_t;
最终,我正在努力分配单个大块内存,并将指针移动到指向大块内存中的适当位置。这个块足够大,以便我可以为data_1和data_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]或其他类似的工作,然后只定义一个结构指针数组,并为每一个分配一个固定的内存大小,但我没有。有各种原因。请坚持我提出的问题。
谢谢!
答案 0 :(得分:3)
首先,malloc()
不分配指针,它为你的struct分配内存,然后它返回一个指向它的指针。完全可能有一个未初始化的指针,或一个指向任何地方的指针(NULL
)。
其次,在C中,有三种类型的变量,分别是:
考虑到这一点你的例子:
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));
这很棘手:my_struct
是一个指针,但是你得到它的地址,所以得到的是指针类型的自动变量my_struct
的地址。
-8之所以发生是因为您要比较两个局部变量的地址:本地指针my_struct
和本地结构变量label
的成员example_struct
。那些恰好在记忆中如此布局。
尝试改为:
printf("Base Address: %p\n", (void*)my_struct);
printf("First Element: %p\n", (void*)&(my_struct->label));
(顺便说一句:在(void*)
时投放到printf("%p")
总是一个好主意。
另一个例子有一个类似的错误:打印结构的地址或指针的值,但不打印指针的地址。
答案 1 :(得分:0)
my_struct
是指向my_structure_t
的指针。无法保证指针与其指向的对象相关的位置。
根据您对内存位置的评论
,我相信您要测试的内容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)
请注意,与您的代码相比,在{2}之前的&
之前删除了my_struct
。
回答您提出的实际问题
另外,为什么内存差异不是0x4而是-0x8?
sizeof(my_structure_t*)
为8,或者编译器确定example_struct
应该是8字节对齐,并在将堆变量添加到堆栈时添加填充。