标签: delete-operator

为什么*必须*删除[]和删除不同?

我很清楚地知道,在C++中,什么delete[]是对new[],deletenew.这与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并且在数组情况下查找内部数据结构之外,我没有看到差异.那么,为什么deletedelete[]不能一直拼写相同?

换句话说,出了什么问题

MyClass *object = new MyClass;
Run Code Online (Sandbox Code Playgroud)

被实施为

MyClass *object = new MyClass[1];
Run Code Online (Sandbox Code Playgroud)

让C++的语法就不会做出区分deletedelete[]

c++ compiler-construction delete-operator

13
推荐指数
2
解决办法
425
查看次数

对从放置new获取的指针使用operator 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)

c++ placement-new language-lawyer delete-operator

12
推荐指数
2
解决办法
1051
查看次数

在使用operator new的展示位置删除结果上调用delete好吗?

如果我做

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++ placement-new new-operator delete-operator

12
推荐指数
2
解决办法
271
查看次数

= delete有什么用途?

今天早些时候我问另一个问题:我=delete什么时候应该使用?我认为没有专门针对=deleteSO 的帖子,所以我在一本名为"The C++ Programming Language"的书中查阅了它.我将在下面的答案中列出我的发现.

如果有更多话要说或者我错了,请评论或回答.

c++ delete-operator c++11

12
推荐指数
1
解决办法
653
查看次数

为什么C++运算符new/delete/variants不应该在头文件中?

有人可以解释这个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)

c++ gcc delete-operator translation-unit

12
推荐指数
1
解决办法
918
查看次数

编写一个函数来释放指针并将其赋值为NULL

我在最近的一次采访中被问到这个问题,基本上是编写了一个函数来结合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,但我不明白为什么它比我做的更好!

c++ delete-operator dangling-pointer

11
推荐指数
2
解决办法
913
查看次数

delete []是否会调用析构函数?

我正在编写一个模板类,它在内部管理给定类型的数组.像这样:

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>.

c++ delete-operator

11
推荐指数
2
解决办法
8433
查看次数

面向对象的自杀或删除此;

以下使用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++ destructor self-destruction delete-operator

10
推荐指数
2
解决办法
2231
查看次数

删除动态分配的2D阵列

所以我习惯于在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)

理解deletedelete[]运营商之间的区别是否重要?或者我可以假设每当我分配一个数组时,ptr = new x[]我还必须解除分配delete[] ptr

c++ memory-management delete-operator

10
推荐指数
1
解决办法
4万
查看次数

为什么删除void*是UB而不是编译错误?

为什么通过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

10
推荐指数
1
解决办法
578
查看次数