确实delete[] a,在那里a被指针的动态分配的数组,执行delete对于在阵列中的每个指针?
我想,它为具有用户定义类的数组执行析构函数,但是指针发生了什么?
我有两个代码块new[]和delete[]:
1)
#include <string>
int main()
{
std::string *p = new std::string[0];
delete[] p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
2)在这种情况下,我只是std::string改为int
int main()
{
int *p = new int[0];
delete[] p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
为什么第一个程序崩溃时出现以下消息(在linux环境中):
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
但第二个程序运行良好没有任何错误?
编辑
编译: g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
我只是使用g++没有任何参数来编译它.
如果是编译器错误,它们是否会根据标准崩溃?
是否可以拥有虚拟删除操作符?我不是在讨论析构函数,我的意思是实际的运算符重载.
减去这个事实(在大多数情况下)重载新的和删除是一个很大的坏主意(是的,我已经知道它是异端),我想知道使用虚拟删除操作符会产生什么样的影响.
我正在考虑尝试使用虚拟删除,因为有时我可能有一个重载delete的子类,存储在基类指针中.从技术上讲,我真的没有看到这种情况会产生过多的结果,除非我有一个不同节点类型的树(如果你问我,首先是潜在的危险想法).
我只是想知道虚拟或非虚拟删除操作符覆盖的潜在优缺点.
c++ virtual inheritance operator-overloading delete-operator
为什么我的MSVC12编译器不喜欢这个?
#include <new>
class thing
{
public:
thing() {}
~thing() {}
static void operator delete(void* ptr) = delete;
};
int main()
{
int g;
void* p = &g;
thing* t1 = new(p) thing();
t1->~thing();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误奇怪地在main()的右括号上:
错误2错误C2280:'void thing :: operator delete(void*)':尝试引用已删除的函数
如果我注释掉显式析构函数调用,则错误消失,暗示显式析构函数调用正在尝试调用operator delete(void*).这没有直观意义.正如您可以从这里的代码中看到的那样,我已经管理了自己的内存,并且我不希望任何人在事物上调用delete.
可能重复:
使用"删除此项"删除当前对象是否可以?
我刚刚看到他们delete this;在类函数中完成的一些代码,我知道这不是一个好的设计,但它定义了会发生什么,让我们说这个类总是来自某个地方的指针.是否会以正确的方式删除它?
class A
{
public:
void abort() { delete this; }
};
class B
{
void func() { A* a = new A; a->abort(); }
};
Run Code Online (Sandbox Code Playgroud) 我有一个char**,基本上是一个字符串数组,我需要删除.这样做的正确方法是什么,以确保所有指针都被清除?
是否delete ptr不同于operator delete(ptr)仅在于此,即delete调用ptr析构函数?或者换句话说,delete ptr首先调用析构函数ptr然后operator delete(ptr)释放已分配的内存吗?然后在delete ptr技术上等同于以下内容:
T * ptr = new T;
//delete ptr equivalent:
ptr->~T();
::operator delete(static_cast<void *>(ptr));
Run Code Online (Sandbox Code Playgroud)
?
在这个问题中,陈述了这个结构防止实例的堆栈分配.
class FS_Only {
~FS_Only() = delete; // disallow stack allocation
};
Run Code Online (Sandbox Code Playgroud)
我的问题是,它如何阻止分配?我理解,无法显式或隐式删除此实例.但我认为,这将分别导致内存泄漏或运行时错误.
编译器是否足够聪明以排除这种情况并引发编译器错误?还有为什么需要这个呢?
在使用g ++的独立上下文(没有标准库,例如在操作系统开发中)中,会出现以下现象:
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
~Derived() {}
};
int main() {
Derived d;
}
Run Code Online (Sandbox Code Playgroud)
链接时,它表示如下: undefined reference to operator delete(void*)
这显然意味着即使动态内存分配为零,g ++也会生成删除运算符的调用.如果析构函数不是虚拟的,则不会发生这种情况.
我怀疑这与课堂生成的vtable有关,但我不完全确定.为什么会这样?
如果由于缺少动态内存分配例程而不能声明删除操作符,是否有解决方法?
EDIT1:
为了成功地重现g ++ 5.1中的问题,我使用了:
g ++ -ffreestanding -nostdlib foo.cpp
operator void*() constC++流类中有一个转换函数.这样所有流对象都可以隐式转换为void*.在与SO的程序员交互过程中,他们建议我不要使用,void*除非你有充分的理由使用它.void*是一种删除类型安全和错误检查的技术.因此,由于该转换功能的存在,以下程序完全有效.这是C++标准库中的一个缺陷.
#include <iostream>
int main()
{
delete std::cout;
delete std::cin;
}
Run Code Online (Sandbox Code Playgroud)
上述程序在C++ 03中有效,但在C++ 11及更高版本的编译器中编译失败,因为此转换函数已被删除.但问题是,如果它是危险的,它是C++标准库的一部分?允许将流对象转换为的目的是void*什么?有什么用?
c++ void-pointers c++-standard-library delete-operator c++11
c++ ×10
delete-operator ×10
pointers ×3
c++11 ×2
destructor ×2
arrays ×1
inheritance ×1
memory ×1
new-operator ×1
this ×1
virtual ×1