请求新操作员的特定地址

Requesting a specific address for the new operator

本文关键字:地址 操作员 请求      更新时间:2023-10-16

假设我想分配一个整数数组。

int* array = new int[5];

然后假设我有 5 个 int 指针,都指向数组的 5 个不同整数。

 int* v1 = &array[0];
 int* v2 = &array[1]; //etc..etc

现在我已经"记住"了数组中所有整数的位置,我想将这些元素作为单独的整数进行管理。所以理论上如果我然后将我的数组指针设置为 NULL......

array = NULL;

理论上我不必担心,因为我所有的 v1 和 v2 指针都指向数组中的所有元素。那么问题是说我已经完成了 v2。所以我想删除 v2 以释放这 4 个字节。

delete v2;

不幸的是,当我尝试这样做时,坏事发生了。我假设是因为内存分配表说"嘿,你不能在该空间中删除,因为它目前属于 int 数组的一部分!

所以没关系,然后我想说

delete [] array;

但如果我这样做,我想确保当我这样做时......

int* v1 = new int;

我想保证新分配的整数是在 array[0] 的地址创建的。那么有没有办法指定创建新值的位置呢?或者我可以以某种方式控制内存列表?

我试图通过调用类似的东西来使用放置运算符...

int* v1 = new((void*)&array[0]) int;

但是当我使用 delete 运算符删除数组然后尝试通过取消引用它来访问 v1 时......说

cout<<*v1;

我在屏幕上看到一堆文字,上面写着"双重免费或损坏(快速顶部(:......

我在代码块中使用 Ubuntu 11.04 和 g++ 编译器。

另外,仅供参考,我已经查看了在特定内存地址创建新C++对象? 这就是我获得有关放置运算符的信息的地方,但它似乎没有按照我需要的方式工作。

#include <iostream>
using namespace std;
int main()
{
int *array = new int[20];
for(int i=0;i<4;i++)
{
    array[i] = i;
}
int* a = new ((void*)&array[0]) int;
int* b = new ((void*)&array[1]) int;
int* c = new ((void*)&array[2]) int;
int* d = new ((void*)&array[3]) int;
int* e = new ((void*)&array[4]) int;
cout<<*a<<endl;
cout.flush();
delete[] array;
cout<<*a;
delete a;
delete b;
delete c;
delete d;
delete e;
return 0;
}
更正

int *v1 = array[0];
int *v2 = array[1];

应该是

int *v1 = array;
int *v2 = array + 1;

此外,如果分配new int[5],则只能为整个数组释放内存,而不能为单个元素释放内存。

"我想保证新分配的整数是在 array[0] 的地址创建的">

如果是这种情况,为什么要选择新分配的整数?只需将array分配给v1,如上所示。

内存分配不能按照您使用的方式工作,您也不能以您尝试的方式释放内存。

放置 new 通过

调用对象的构造函数在给定位置"创建"对象,但不分配内存,因此放置 new 使用的内存不能通过删除释放。内存应在调用放置 new 之前进行预分配,并且可以根据预分配的方式释放内存。

用法:放置新。另外,我从博客(不是我的(中找到了一个示例:放置新

delete v2;

您不应该删除单独分配的元素 放置 new,在完成放置后一次释放所有内存,就像这个delete [] array;(有关更详细的说明(。

并更新您的代码:

#include <iostream>
using namespace std;
int main()
{
    int *array = new int[20];
    for(int i=0;i<5;i++) // Still leaves garbage in rest of array
    {
        array[i] = i; 
    }
    int* a = new (array) int; 
    // int* a = new(&array[0]) int;
    int* b = new (array + 1) int;
    int* c = new (array + 2) int;
    int* d = new (array + 3) int;
    int* e = new (array + 4) int;
    cout << *a << " " << *b << " " << *c << " " << *d << " " << *e << endl;
    delete[] array;
 }

几个提示:

1(cout.flush();是不必要的,因为std::endl已经调用flush()了。

2(我认为没有理由在这里使用放置新位置,看看这个SO问题,看看你应该使用它的原因。在上面的示例中,int array[5];int* a = array;就可以了。此外,在链表中的想法是可以轻松插入和删除元素,如果您分配数组,则无法删除数组并期望之后能够使用内存(这将导致 UB(。所以你必须在使用数组或链表之间进行选择,你不能同时拥有两者(好吧,你可以在一定程度上模拟链表(。

3(就像我上面提到的,在使用完内存后调用delete [] array;,不要取消引用该内存中的指针,或者在释放内存后调用删除指针进入该内存。