当前位置:  开发笔记 > 编程语言 > 正文

为什么malloc分配的字节数与请求的数不同?

如何解决《为什么malloc分配的字节数与请求的数不同?》经验,为你挑选了5个好方法。

我有这段代码

#include 
#include 
#include 
#include 

int main(){
    void *a, *b;

    a = malloc(16);
    b = malloc(16);
    printf("\n   block size (for a): %p-%p : %li", b, a, b-a);

    a = malloc(1024);
    b = malloc(1024);
    printf("\n   block size (for a): %p-%p : %li", b, a, b-a);  
}

这不应该打印最后分配的块大小(16或1024)?它改为打印24和1032,因此分配的内存量似乎有8个额外的字节.

我的问题是(在进行此测试用例之前)我malloc()在一个函数(1024字节)中执行,并返回分配的结果.在函数返回时检查块大小时,我得到了516个块......我不明白为什么.我想这可能是在对分配的缓冲区进行一些处理后发生内存损坏的原因:)

编辑:我已经看过如何从C中的指针获取数组的大小?似乎问了同样的事情,抱歉转发.

我已经将我的示例重新编写为更具体的代码:

#include 
#include 
#include 
#include 

short int * mallocStuff(long int number, short int base){
    short int *array;
    int size=1024;

    array=(short int*)calloc(1,size);
    //array=(short int*)malloc(size);

    return array;
}

int main(){
    short int **translatedArray;

    translatedArray=malloc(4*sizeof(short int));

    int i;
    for(i=0;i<4;i++){
        translatedArray[i]=mallocStuff(0,0);

        if(i>0)
            printf("\n   block size (for a): %p-%p : %i",
                translatedArray[i], translatedArray[i-1], translatedArray[i]-translatedArray[i-1]);
    }

    return 0;
}

输出是

   block size (for a): 0x804a420-0x804a018 : 516
   block size (for a): 0x804a828-0x804a420 : 516
   block size (for a): 0x804ac30-0x804a828 : 516

根据上面大于1024的帖子.我错了吗?



1> SquareCog..:

首先,Malloc不保证两个连续的malloc调用返回连续的指针.

其次,根据您的具体架构,适用不同的对齐规则; 有时你可能会要求一个字节,但架构更喜欢8字节或4字节间隔的分配.

第三,malloc需要一些开销来存储分配块的大小等.

不要假设malloc正在做什么,而不是文档所说的!



2> Greg Hewgill..:

malloc函数总是分配比您要求的更多,以便存储一些簿记信息.毕竟,当你打电话时,free()它需要知道块有多大.

此外,通常malloc实现将所请求的大小四舍五入到下一个8或16的倍数或一些其他的round-ish数.

更新:您的问题的真正答案在于您使用该short int类型.在类型指针之间进行指针运算(减法)时,C和C++返回指向的事物数量的差异.由于您指向的short int是大小为两个字节,因此返回的值是您期望的一半.

另一方面,无论你将结果投射到后来,malloc总是分配给定数量的字节.试试这个:

    array=(short int*)malloc(sizeof(short int) * size);



3> Mike Hearn..:

无法保证两个malloc调用返回完全打包在一起的块 - 实际上根本没有任何关于结果的保证,除非它是非NULL,它将指向一个与请求的块一样大的块.

在内部,大多数malloc都保存工作数据以帮助他们管理堆.例如,这8个字节可能包含两个指针 - 一个指向下一个块,一个指向前一个块.我不知道这8个字节是什么,因为你没有提到你正在运行的操作系统,但是malloc在幕后使用一些内存是完全正常的.

一些分配器(例如,在窗口上)提供了一个库函数来发现给定指针的块大小,但是,有些不这样做,因为它是一个相当深奥的特性.



4> P Daddy..:

你有一个bug.代替:

translatedArray=malloc(4*sizeof(short int));

你应该有

translatedArray=malloc(4*sizeof(short int*));

请注意代码中缺少的指针.我怀疑这是你观察到的行为源于何处.


另请注意0x804a420 - 0x804a018 = 1032,不是516.该公式translatedArray[i] - translatedArray[i - 1]为您提供两个地址之间的元素数(短整数,或更简单地说,短路),而不是字节数.



5> Mongoose..:

malloc返回的内容取决于malloc的实现和体系结构.正如其他人已经说过的那样,您可以保证达到所需的内存量,或者为NULL.这也是为什么有时你可以写一个数组的末尾,而不是一个分段错误.这是因为你实际上有权访问这个内存,你只是不知道它.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有