为什么两个指针都具有相同的内存地址?

时间:2019-01-27 10:49:27

标签: c++ new-operator placement-new

#include <iostream>

using namespace std;

int main()
{
    char* MainBlock = new char[100];

    char* SubBlock1 = new (MainBlock) char[20];

    char* SubBlock2 = new (MainBlock) char [20];

    cout  << static_cast<void*>(SubBlock1) << " " << static_cast<void*>(SubBlock2);


}

为什么上面代码中的两个指针都具有相同的地址?我希望SubBlock2在SubBlock 1之后是20个字节。

这是否意味着即使我只有100个字节,我也可以分配无数个指针,且其位置为new?

如何使用新的展示位置确保SubBlock6将为nullptr或超出范围?

3 个答案:

答案 0 :(得分:2)

  

为什么上面代码中的两个指针都具有相同的地址?

placement new接受将用于初始化正在创建的对象的确切地址。您传递相同的地址,您获得相同的地址。

  

这是否意味着即使我只有100个字节,我也可以分配无数个指针,且其位置为new?

不。每个新的布置都会重复使用存储。您当然可以无限次地重复使用存储,但是最多只能分配相同的100个字符。

  

如何使用新的展示位置确保SubBlock6将为nullptr或超出范围?

没有办法。开始是在 you 上,以提供有效的存储空间来放置新对象以创建对象。如果不这样做,则行为是不确定的。

最后,您不需要为新的展示位置而烦恼。

char *SubBlock1 = MainBlock;
char *SubBlock2 = MainBlock + 20;

对缓冲区进行分区就可以了。只要确保仅delete[] MainBlock中存储的指针值即可。

答案 1 :(得分:1)

(MainBlock)参数是 placement 参数。实际上,您实际上是在明确告诉程序要在SubBlock1的地址上同时分配SubBlock2MainBlock

答案 2 :(得分:0)

每个获取new expression的地址将调用相应的allocation function。完成分配并从分配函数返回地址后,它将尝试在指定的地址处精确构造对象。

给出char* SubBlock1 = new (MainBlock) char[20];,它调用以下分配函数:

  

void* operator new[]( std::size_t count, void* ptr );

     

由标准数组形式放置新表达式调用。标准库实现不执行任何操作,并返回未修改的ptr。

如上面的文档所述,调用此分配函数不会执行任何操作,并返回您传递的未经修改的地址。因此,此新表达式正好在char处构造20 MainBlock。这就是为什么SubBlock1SubBlock2都获得相同地址的原因。


  

这是否意味着即使我只有100个字节,我也可以分配无数个指针,且其位置为new?

不。请注意,分配构造是两回事。在您的示例中,您仅分配一次内存,并在其上多次构造对象。因此,在分配的内存上构造对象的布局由您决定。