c – 为什么新的第一次分配1040个额外字节?
发布时间:2020-12-16 10:06:58 所属栏目:百科 来源:网络整理
导读:我正在创建这个简单的测试程序来演示使用标准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 pri
我正在创建这个简单的测试程序来演示使用标准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.sizen"; // 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,0xa0ec20 BLOCK 1: 08b,0xa0f050,1072b BLOCK 2: 16b,0xa0f070,32b BLOCK 3: 16b,0xa0f090,32b BLOCK 4: 04b,0xa0f0b0,32b BLOCK 5: 04b,0xa0f0d0,32b BLOCK 6: 06b,0xa0f0f0,32b BLOCK 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,0x1f47030 BLOCK 1: 08b,0x1f47050,32b BLOCK 2: 16b,0x1f47070,0x1f47090,0x1f470b0,0x1f470d0,0x1f470f0,0x1f47110,32b 这是正常的预期结果.是什么让新手在首次运行中以如此奇怪的方式表现?我正在使用g(GCC)7.1.1 20170516.您可以编译而不进行优化,结果是相同的. 解决方法
你会惊讶地发现你的程序不仅仅是做一些内存分配.
std::cout << "BLOCK " << num << ": "; 您的程序还生成格式化输出到std :: cout,利用其内置的 很明显,std :: cout的第一个输出为内部std :: streambuf分配了一个1024字节的缓冲区.这是在您第一次新分配之后和第二次分配之前发生的.缓冲区只需要在第一次使用时分配一次. 虽然不言而喻,内部存储器分配的细节是高度实现定义的,但这似乎是您案例中最可能的解释. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |