请求新操作员的特定地址
Requesting a specific address for the new operator
假设我想分配一个整数数组。
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;
,不要取消引用该内存中的指针,或者在释放内存后调用删除指针进入该内存。
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 如何在c++程序中找到函数的地址
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 被解释为低级别const的const对象的地址
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 内联程序集printf将整数解释为地址
- 为什么指针不写入类的地址?
- 如何在C++中获取该对象的类声明中对象的地址?
- 通过按地址访问变量
- <<操作员在下面的行中工作
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 函数名是c中该函数的第一条指令的地址吗
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 操作员的地址可以启动指针,但填充值是垃圾
- 带有超载操作员 的无访问地址的指针返回
- 请求新操作员的特定地址