c – 为什么新的第一次分配1040个额外字节?

c – 为什么新的第一次分配1040个额外字节?,第1张

概述我正在创建这个简单的测试程序来演示使用标准new分配内存时对齐的工作方式… #include <iostream>#include <iomanip>#include <cstdint>//// Print a reserved block: its asked size, its start address // and the size of the previous 我正在创建这个简单的测试程序来演示使用标准new分配内存时对齐的工作方式…

#include <iostream>#include <iomanip>#include <cstdint>//// Print a reserved block: its asked size,its start address //       and the size of the prevIoUs reserved block//voID print(uint16_t num,uint16_t size_asked,uint8_t* p) {   static uint8_t* last = nullptr;   std::cout << "BLOCK " << num << ":   ";   std::cout << std::setfill('0') << std::setw(2) << size_asked << "b,";    std::cout << std::hex << (voID*)p;   if (last != nullptr) {      std::cout << "," << std::dec << (uint32_t)(p - last) << "b";   }   std::cout << "\n";   last = p;}int main(voID) {   // Sizes of the blocks to be reserved and pointers   uint16_t s[8] = { 8,8,16,4,6,6 };   uint8_t* p[8];   // Reserve some consecutive memory blocks and print   // pointers (start) and their real sizes//   std::cout << "          size   start    prev.size\n";//   std::cout << "-----------------------------------\n";   for(uint16_t i = 0; i < 8; ++i) {      p[i] = new uint8_t[s[i]];      print(i,s[i],p[i]);   }   return 0;}

但是当我执行程序时,我发现了这种奇怪的行为:

[memtest]$g++ -O2 mem.cpp -o mem[memtest]$./mem BLOCK 0:   08b,0xa0ec20BLOCK 1:   08b,0xa0f050,1072bBLOCK 2:   16b,0xa0f070,32bBLOCK 3:   16b,0xa0f090,32bBLOCK 4:   04b,0xa0f0b0,32bBLOCK 5:   04b,0xa0f0d0,32bBLOCK 6:   06b,0xa0f0f0,32bBLOCK 7:   06b,0xa0f110,32b

如您所见,new分配的第二个块不是在下一个32b内存的对齐地址,而是远在(1040个字节以外).如果这不够奇怪,取消注释打印出表头的2 std :: cout行会产生以下结果:

[memtest]$g++ -O2 mem.cpp -o mem[memtest]$./mem           size   start    prev.size-----------------------------------BLOCK 0:   08b,0x1f47030BLOCK 1:   08b,0x1f47050,32bBLOCK 2:   16b,0x1f47070,0x1f47090,0x1f470b0,0x1f470d0,0x1f470f0,0x1f47110,32b

这是正常的预期结果.是什么让新手在首次运行中以如此奇怪的方式表现?我正在使用g(GCC)7.1.1 20170516.您可以编译而不进行优化,结果是相同的.

解决方法 你会惊讶地发现你的程序不仅仅是做一些内存分配.

std::cout << "BLOCK " << num << ":   ";

您的程序还生成格式化输出到std :: cout,利用其内置的std::streambuf.

很明显,std :: cout的第一个输出为内部std :: streambuf分配了一个1024字节的缓冲区.这是在您第一次新分配之后和第二次分配之前发生的.缓冲区只需要在第一次使用时分配一次.

虽然不言而喻,内部存储器分配的细节是高度实现定义的,但这似乎是您案例中最可能的解释.

总结

以上是内存溢出为你收集整理的c – 为什么新的第一次分配1040个额外字节?全部内容,希望文章能够帮你解决c – 为什么新的第一次分配1040个额外字节?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1217748.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存