使用Malloc更改指针地址

使用Malloc更改指针地址,c,C,下面是代码片段: void main() { int i,*s; for(i=1;i<=4;i++) { s=malloc(sizeof(int)); printf("%lu \n",(unsigned long)s); } } 为什么会这样?malloc()不提供任何此类保证。它只是根据自己的内存管理决定分配一些内存,并返回指向该内存的指针。事实上,许多实现在指针返回内存管理元数据之前就使用了额外的内存。您无法保证地址模式malloc返回给您。

下面是代码片段:

void main() {
   int i,*s;
   for(i=1;i<=4;i++) {
      s=malloc(sizeof(int));
      printf("%lu \n",(unsigned long)s);
   }
}

为什么会这样?

malloc()
不提供任何此类保证。它只是根据自己的内存管理决定分配一些内存,并返回指向该内存的指针。事实上,许多实现在指针返回内存管理元数据之前就使用了额外的内存。

您无法保证地址模式
malloc
返回给您。

它被称为对齐。大多数CPU必须在某个边界上对齐内存,通常为4或8。如果地址对齐错误,将出现segfault或总线错误。

内存管理方式完全取决于操作系统。它可以从任何地方分配内存,你绝对不能假设内存会在哪里

大多数内存分配器也有一些开销,因此即使是简单的2字节分配也可能占用8字节或更多。此外,地址可能需要对齐有几个原因(比如性能,还有一些CPU甚至在读取未对齐的地址时崩溃)

底线-按原样从malloc获取返回值,不要做任何猜测或假设。

malloc()
提供了对底层硬件、操作系统、驱动程序等的抽象。内存分配模式可能因不同的参数而不同

但是关于
malloc()

  • malloc()
    函数分配
    size
    字节,并返回指向分配内存的指针
  • 内存未初始化
  • 如果
    size
    为0,则
    malloc()
    返回
    NULL
    ,或者返回一个唯一的指针值,该值可以在以后成功传递到
    free()
  • malloc()。出现错误时,它返回
    NULL
  • NULL
    也可以通过成功调用大小为
    0的
    malloc()
    返回
  • 另一方面,您可以使用
    %p
    格式说明符来打印指针

    我修改了程序如下

    #include <stdlib.h>
    
    int main(void) {
        int i,*s;
        printf("sizeof(int) = %zu \n", sizeof(int));
    
        for(i=1;i<=4;i++) {
            if ((s=malloc(sizeof(int))) == NULL) {
                printf("unable to allocate memory \n");
                return -1;
            }
            printf("%p \n",s);
         }
    
         return 0;
    }
    

    malloc
    可以在您的地址空间中返回所有地址。您的处理器体系结构是什么?您使用的是谁的
    malloc
    ?正如@Mat所说,您不能对malloc返回的地址做出任何假设-通常情况下,虽然在您的情况下,有一个最小对齐和最小大小分配,看起来是8字节。我不知道有哪一个平台具有8字节对齐边界,而不是托管系统。由于您在托管系统上使用的是void main(),因此您的代码不应在C编译器上编译。除了给定平台+1的最小对齐之外,没有任何保证,我建议不要分配4个甚至8个字节的块,因为簿记和对齐开销通常会消耗至少两倍以上的开销。当然,除非您编写自己的超级专用分配器,它是为小型分配而设计的。但在正常生活中,由于许多原因,这些小的分配是不好的。+1,8字节对齐在目标上很常见,其中double和long long必须以这种方式对齐,因此malloc必须始终返回一个适用于所有情况的地址。如果分配的2字节对象太多,导致开销成为问题,请一次为1000个对象分配空间,然后编写一个自己的函数来分配它们。如果您将对该块的分配限制为特定的算法,那么您可以在完成后一次释放整个块,并通过这种方式节省时间,更不用说减少内存碎片了返回一个指向已分配内存的指针,该内存针对任何类型的变量进行了适当的对齐——这在Windows和Linux的情况下都不是这样,因为SSE需要16字节对齐,但Win32/Linux malloc通常只对齐8字节。-1对于在C中类型转换malloc的结果,您永远不应该这样做@伦丁点注意到了!当然,在使用
    malloc()
    时不包括
    stdlib.h
    是非常蹩脚的。这不是唯一可能发生的问题。malloc()返回一个void*,它可以被广泛地转换成很多东西。例如,使用typecast,您可以轻松编写如下错误:
    typet=(Type)malloc(sizeof(Type))其中类型是整数类型而不是指针。在没有打印类型的情况下,您应该得到警告。在打印<代码> SIZEOF(INT)时,请考虑使用<代码> %ZU>代码>格式说明符。
    
    #include <stdlib.h>
    
    int main(void) {
        int i,*s;
        printf("sizeof(int) = %zu \n", sizeof(int));
    
        for(i=1;i<=4;i++) {
            if ((s=malloc(sizeof(int))) == NULL) {
                printf("unable to allocate memory \n");
                return -1;
            }
            printf("%p \n",s);
         }
    
         return 0;
    }
    
    $ ./a.out 
    sizeof(int) = 4 
    0x9d5a008 
    0x9d5a018 
    0x9d5a028 
    0x9d5a038 
    $