c结构指针在堆中有内存,但在打印其大小时,通过使指针指向一个回基地址,然后出现分段错误



当打印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));

相关内容

  • 没有找到相关文章