繁体   English   中英

将内存分配给void *时的gcc calloc行为

[英]gcc calloc behavior when allocating memory to void*

我知道这不是使用void指针的好方法,但是我对此行为感到好奇。

int main()
{
    void* ptr;
    void* next;
    ptr = ::operator new(8);
    next = (void*)((char*)ptr + 1) ;
    *(int*)next = 90;
    *(int*)ptr =100;
    cout << "Ptr = " << ptr<<endl;
    cout << "Ptr-> " << *(int*)ptr<<endl;
    cout << "Next = " << next<<endl;
    cout << "Next-> " << *(int*)next<<endl;
}

---------------
Result :
Ptr = 0x234e010
Ptr-> 100
Next = 0x234e011
Next-> 0
---------------

在64位(x86_64)和32位(x86)平台(Linux和Windows)上,当向ptr添加超过4个字节时,next指向的位置将保留90,但是当添加少于4个字节时,

*执行* ptr = 100时,* next突然变为0,与calloc和malloc相同

为什么要更改ptr point位置的内容必须更改ptr + 1 point的位置? 为什么当我们超过4个字节时这种情况不会发生? 如果是关于内存对齐的,为什么在32位和64位平台上都有相同的行为?

在delphi中也相同的结果(Windows 32bit / Embarcadero)

谢谢,抱歉我的英语不好

当您使用X86体系结构时,对齐将不会成为问题:即使速度较慢,处理器也可以访问未对齐的内存。

英特尔处理器以最低有效字节FIRST存储数据。 Google对字节序进行了更深入的解释。 发生的是

vvvvvvvvvvvvvvvv  this is Ptr
+===+===+===+===+===+===+===+===+
|   |100| 0 | 0 | 0 |   |   |   |
+===+===+===+===+===+===+===+===+
    ^^^^^^^^^^^^^^^^ this is next after you say '*next=100'

现在,当您将90存储到* Ptr时,将更改为

vvvvvvvvvvvvvvvv  this is Ptr
+===+===+===+===+===+===+===+===+
| 90| 0 | 0 | 0 | 0 |   |   |   |
+===+===+===+===+===+===+===+===+
    ^^^^^^^^^^^^^^^^ this is next

所以next变为0,因为其前3个字节被0覆盖,而最后一个字节始终为0。

ints(通常)为4个字节。 您仅向ptr的下一个字节添加了一个字节,而不是4。这意味着ptr和next重叠,因此您分配100会破坏90的最后一个字节(恰好是0)。

你需要:

next = (void*)((char*)ptr + sizeof(int));

实际上,您只需要使用正确键入的指针即可。

似乎正在发生的事情是,每次操作后,内存的八个字节具有以下内容:

*(int*)next = 90; // 90  == 0x00 00 00 5A
--> 0x?? 5A 00 00 00 ?? ?? ??
*(int*)ptr = 100; // 100 == 0x00 00 00 64 
--> 0x64 00 00 00 00 ?? ?? ??

结果, *(int*)next现在等于零。 请注意,您不能指望此行为,因为它取决于基础硬件。

这与分配或void *无关,与您对值如何存储在内存中的假设无关。

您将一个int(在系统中占4个字节的单元)写入地址101,然后又将另一个写入地址100,覆盖第一个值3。

不幸的是,您所使用的系统未使用您假设的字节序/字节顺序,由此第一个值的lsb将占据地址104。结果是,第二次写操作的四个零字节之一使第一个值零。

这是因为您使用char偏移量调用tint int值来调用未定义的行为。

当int变为8个字节时,任何使用自己的指针手动操作的人都会遇到相同的问题。

顺便说一句,您应该能够以此形式告诉您有关系统数字表示形式的词序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM