当打印malloc为结构指针分配的大小时,抛出分段错误,但对整数指针有利?
malloc大小可以一次返回到它的基地址,我正在取消引用它以获得大小,但结构指针出现分段错误,但如果它是整数或字符指针,那么它很好,请任何人解释一下?
#include<stdio.h>
#include<stdlib.h>
struct st
{
int roll;
char name[10];
};
int main()
{
struct st *p,var[3];
p=malloc(sizeof(struct st)); // here i allocating memory in heap
printf("%dn",*(p-1)); // printing allocated memory it good when *p is interger pointer but if structure pointer then it throw segmentation fault why?
}
警告:您的应用程序依赖于特定堆实现的实现细节,它不受C标准支持,并且可能在其他系统上中断。
问题来了。在堆实现中,堆块的大小存储在堆块本身之前。这有助于free
释放适当数量的内存。下图展示了这一点:
Lower memory ^^^
...
+----------------+
| size (4 bytes) |
+----------------+
p -> | struct st |
| ... |
+----------------+
在C中,当您执行指针算术时,指针会被调整为与它所指向的对象相同的字节数。对于整数指针,它们会被调整4个字节(假设您使用的是32个整数)。正如您所声称的那样,我们可以假设这是调整指针以查找大小字段的正确字节数。
然而,对于结构指针,指针被调整为sizeof(struct st)
,在大多数系统上,这是16个字节(14个用于实际内容,另外两个用于填充结构,以确保int
成员的正确对齐,如果结构用于数组中)。执行(p-1)
时,将指针调整为16个字节。此外,当您执行*(p-1)
时,您将整个结构传递给printf
,这是printf
所没有预料到的。这很可能是这次事故的原因。
那么,你能做什么呢?这个问题的最好答案是不要,因为这是不正确的。第二个最好的答案是写一些明确描述你所做的事情,并且可以调整以匹配其他系统,例如:
#define OFFSET_TO_HEAP_SIZE 4
#define HEAP_SIZE_TYPE uint32_t
* ( (HEAP_SIZE_TYPE *)(((char const *)p) - OFFSET_TO_HEAP_SIZE) )
当您执行p=malloc(sizeof(struct-st))时;P将被分配(4+10+2(填充))字节,假设P指向地址1000
*(p-1)将尝试访问(1000-16)地址处的值,该值是随机的,甚至可能没有被分配。
这就是为什么*(p)会起作用,而*(p-1)不起作用。
问题是printf("%dn",*(p-1));
。你的代码有一些问题:
1。你正在向后移动一个地址,然后寻找p的值。
2。不能将指向结构的指针的值打印为整数。您可以使用p指针打印位于结构中的整数的值。
3。结构中的滚动值未初始化。
首先初始化结构中的滚动值,然后打印:
printf("%dn", (*p).roll);
或
printf("%dn", (p->roll));
如果你想打印分配给*p的内存量,只需写:
printf("%ld", sizeof(struct st));