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

问题描述 投票:1回答:3
#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个字节,我可以分配无限数量的指针与新的位置?

如何使用placement new确保SubBlock6是nullptr还是越界?

c++ new-operator placement-new
3个回答
2
投票

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

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

这是否意味着即使我只有100个字节,我可以分配无限数量的指针与新的位置?

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

如何使用placement new确保SubBlock6是nullptr还是越界?

不可能。一开始就是为您提供有效的存储空间以便创建对象。如果不这样做,则行为未定义。

最后,您不需要放置新的放置。

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

将缓冲区分区就好了。只要确保delete[]只存储在MainBlock中的指针值。


1
投票

(MainBlock)参数是一个放置参数。事实上,你明确告诉程序在SubBlock1的地址分配SubBlock2MainBlock


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个字节,我可以分配无限数量的指针与新的位置?

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

© www.soinside.com 2019 - 2024. All rights reserved.