我很清楚地知道,在C++中,什么delete[]是对new[],delete是new.这与C++语法无关.我想知道原因 delete[]被定义为与平原不同的东西delete.这有什么实施原因?
考虑一下这段代码会发生什么:
MyClass *object = new MyClass;
delete object;
Run Code Online (Sandbox Code Playgroud)
当delete遇到存储器管理器具有查找在其分配结构,不管它是对象指针值,并标记对应sizeof(MyClass)的存储器作为自由块.
现在考虑一下这段代码会发生什么:
MyClass *array = new MyClass[ num_objects ];
delete [] array;
Run Code Online (Sandbox Code Playgroud)
当delete遇到存储器管理器具有查找在其分配结构数组指针值,不管它是,发现num_objects从该结构值,并标记对应num_objects*sizeof(MyClass)的存储器作为自由块.
除了num_objects在单个对象案例中假设1并且在数组情况下查找内部数据结构之外,我没有看到差异.那么,为什么delete并delete[]不能一直拼写相同?
换句话说,出了什么问题
MyClass *object = new MyClass;
Run Code Online (Sandbox Code Playgroud)
被实施为
MyClass *object = new MyClass[1];
Run Code Online (Sandbox Code Playgroud)
让C++的语法就不会做出区分delete和delete[]?
我确信这段代码应该是非法的,因为它显然不会起作用,但它似乎被C++ 0x FCD所允许.
class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X(); // according to the standard, the RHS is a placement-new expression
::operator delete(p); // definitely wrong, per litb's answer
delete p; // legal? I hope not
Run Code Online (Sandbox Code Playgroud)
也许你们中的一位语言律师可以解释标准如何禁止这一点.
还有一个数组形式:
class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X[1]; // according to the standard, the RHS is a placement-new expression
::operator delete[](p); // definitely …Run Code Online (Sandbox Code Playgroud) 如果我做
struct MyStruct { ~MyStruct() { } };
void *buffer = operator new(1024);
MyStruct *p = new(buffer) MyStruct();
// ...
delete p; // <---------- is this okay?
Run Code Online (Sandbox Code Playgroud)
是delete保证照顾两个呼叫~MyStruct() 以及 operator delete?
有人可以解释这个C++编译错误的本质吗?我正在涉及/学习重载全局运算符new,delete及其变体.我读了一对夫妇 的 文章 上 的 主题,但我无法找到一个似乎专门解决这个问题.
代码
foo.h:
#ifndef foo_h
#define foo_h
void* operator new(size_t);
void* operator new[](size_t);
void operator delete(void*);
void operator delete[](void*);
#endif // foo_h
Run Code Online (Sandbox Code Playgroud)
foo.cpp:
#include <foo.h>
#include <iostream>
void* operator new(size_t size) { return NULL; }
void* operator new[](size_t size) { return NULL; }
void operator delete(void* p) { }
void operator delete[](void* p) { }
Run Code Online (Sandbox Code Playgroud)
编译错误
>g++ -g -std=c++14 -I./ -c foo.cpp -o foo.o
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33, …Run Code Online (Sandbox Code Playgroud) 我在最近的一次采访中被问到这个问题,基本上是编写了一个函数来结合free的功能和赋值null.我用以下方式回答:
void main()
{
int *ptr;
ptr = new int;
ptr = newdelete(ptr);
}
(int*) newdelete (int *ptr)
{
delete(ptr);
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
因此在执行之后,当我从函数返回时,ptr本地main将保持空值newdelete.如果我刚刚NULL在newdelete函数中分配,则ptr本地newdelete将被取消,而不是ptr本地的main.
我认为我的解决方案是正确的,面试官也接受了.但是,他期待着其他一些答案.他坚持要求我不NULL从函数返回并仍然达到预期的效果.
有没有办法实现这一目标?我能想到的只是传递另一个参数,它是指向ptr本地指针的指针main,但我不明白为什么它比我做的更好!
我正在编写一个模板类,它在内部管理给定类型的数组.像这样:
template<typename T>
class Example {
// ...
private:
T* objects; // allocated in c'tor (array), deleted in d'tor
// ...
};
Run Code Online (Sandbox Code Playgroud)
我想知道objects当我删除它时,C++是否会调用每个对象的析构函数delete[] objects;.
我需要知道这一点,因为我的类中的对象始终不包含合理的值,因此不应该在不执行时调用析构函数.
此外,我想知道,如果我宣布一个固定大小的数组像析构函数将被称为T objects[100]作为的一部分Example<T>.
以下使用MSVC9.0编译的代码运行并输出Destructor四次,这是合乎逻辑的.
#include <iostream>
class SomeClass
{
public:
void CommitSuicide()
{
delete this;
}
void Reincarnate()
{
this->~SomeClass();
new (this) SomeClass;
}
~SomeClass()
{
std::cout << "Destructor\n";
}
};
int main()
{
SomeClass* p = new SomeClass;
p->CommitSuicide();
p = new SomeClass;
p->Reincarnate();
p->~SomeClass(); //line 5
p->CommitSuicide();
}
Run Code Online (Sandbox Code Playgroud)
我认为main中的前4行代码不会导致未定义的行为(尽管不完全确定delete this;).我想要确认或<占位符确认的反义词>.但我对第5行和第6行有严重怀疑.允许显式调用析构函数,不是吗?但在此之后,对象的生命周期是否已经完成?也就是说,在析构函数的显式调用允许(定义)后调用另一个成员?
总而言之,上述代码的哪些部分(如果有的话)会导致未定义的行为(从技术上讲)?
所以我习惯于在C中进行内存管理,这free(pointer)将释放所有指向的空间pointer.现在,当我尝试用C++做一些简单的事情时,我会感到困惑.
如果我有一个二维数组的双精度分配方式与此类似
double** atoms = new double*[1000];
for(int i = 0; i < 1000; i++)
atoms[i] = new double[4];
Run Code Online (Sandbox Code Playgroud)
什么是释放新分配的堆上的内存的正确方法?
我的想法原来是这样的(因为我的大脑在用C思考):
for(int i = 0; i < 1000; i++)
delete atoms[i];
delete atoms;
Run Code Online (Sandbox Code Playgroud)
但是我忘记了delete[]运算符的存在,所以我相信正确的方法如下:
for(int i = 0; i < 1000; i++)
delete[] atoms[i];
delete[] atoms;
Run Code Online (Sandbox Code Playgroud)
理解delete和delete[]运营商之间的区别是否重要?或者我可以假设每当我分配一个数组时,ptr = new x[]我还必须解除分配delete[] ptr?
为什么通过void*未定义的行为而不是编译错误来删除对象?
void foo(void* p) {
delete p;
}
Run Code Online (Sandbox Code Playgroud)
这段代码编译并生成代码,虽然gcc和clang上有警告(令人惊讶的是,ICC没有发出警告):
:2:5:警告:无法删除带有指针''''''的类型'void*'[-Wdelete-incomplete]
为什么不是简单的格式错误的程序,语法无效?貌似标准没有花太多时间就可以了,在说[expr.delete]这
这意味着无法使用void*类型的指针删除对象,因为void不是对象类型.
我有什么理由不知道为什么这不会触发硬编译错误?
c++ void-pointers undefined-behavior language-lawyer delete-operator