灵感来自这个问题.
假设在C++代码中我有一个有效的指针并且正确delete.根据C++标准,指针将变为无效(3.7.3.2/4 - 解除分配函数将使所有指针无效,指向解除分配的存储的所有部分).
至少在大多数实现中,它保留了值并将存储与以前完全相同的地址delete,但是使用该值是未定义的行为.
标准是否保证指针将保留其值或允许更改的值?
在C++中,如果要动态分配数组,可以执行以下操作:
int *p;
p = new int[i]; // i is some number
Run Code Online (Sandbox Code Playgroud)
但是,要删除数组,你要...
delete[] p;
Run Code Online (Sandbox Code Playgroud)
为什么不呢delete p[]?这与它最初创建的方式不会更加对称吗?是什么原因(如果有的话)为什么语言是这样设计的?
c++ language-design dynamic-memory-allocation delete-operator
我读过这个问题,但它对我来说仍然没有多大意义.它听起来更像是糖衣涂层功能.
有什么区别:
class A
{
// public/private ?
A (const A&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
和
class A
{
private:
A (const A&); // MISSING implementation
};
Run Code Online (Sandbox Code Playgroud)
相同operator=或其他功能.
我试图在其中召唤::delete一堂课operator delete。但是不调用析构函数。
我定义的类MyClass,其operator delete过载。全局operator delete也超载。重载operator delete的MyClass将调用重载的全局operator delete。
class MyClass
{
public:
MyClass() { printf("Constructing MyClass...\n"); }
virtual ~MyClass() { printf("Destroying MyClass...\n"); }
void* operator new(size_t size)
{
printf("Newing MyClass...\n");
void* p = ::new MyClass();
printf("End of newing MyClass...\n");
return p;
}
void operator delete(void* p)
{
printf("Deleting MyClass...\n");
::delete p; // Why is the destructor not called here?
printf("End of deleting MyClass...\n");
}
}; …Run Code Online (Sandbox Code Playgroud) 使用运算符 new() 创建类 C 的新对象会在此处出现错误:
class C
{
public:
C() {}
virtual ~C() {}
void operator delete(void*) = delete;
};
int main()
{
C* c = new C;
}
Run Code Online (Sandbox Code Playgroud)
和 C2280: 'void C::operator delete(void *)': function was explicitly deleted
但是,当我更换C() {}
使用C() = default;
或删除线,使编译器插入一个默认的构造函数(我相信有同样的效果= default),该代码将编译并运行。
使这种情况发生的编译器生成的默认构造函数和用户定义的默认构造函数之间有什么区别?
我在这篇文章中得到了一些提示,但是这里的 C 类(没有用户提供的构造函数)并不是微不足道的,因为析构函数是虚拟的,对吧?
使用最新的 Visual Studio,c++17 编译。
我在代码库中发现了经典的新/删除不匹配错误,如下所示:
char *foo = new char[10];
// do something
delete foo; // instead of delete[] foo;
Run Code Online (Sandbox Code Playgroud)
这有多严重?它是否会导致内存泄漏或错误?有什么后果.我们有一些内存问题,但这似乎不足以解释我们所有的症状(堆损坏等)
编辑:清晰的额外问题
它是否只释放阵列的第一个成员?还是
会让系统失去对阵列的追踪?或
腐败记忆是某种方式?
确实delete[] a,在那里a被指针的动态分配的数组,执行delete对于在阵列中的每个指针?
我想,它为具有用户定义类的数组执行析构函数,但是指针发生了什么?
如果两个库(动态链接)有自己的全局覆盖版本的new和delete运算符并且他们使用自己的内存管理会发生什么?
在库中运送内存管理工具通常是错误的,还是在某些情况下仅为某些特定类提供内存管理是好的,只定义特定于类的新操作符和删除操作符覆盖?
在静态链接库的情况下是否存在一些差异?
我在下一个代码中遇到分段错误异常:
class A {
public:
A() {}
virtual ~A(){}
double m_d;
};
class B : public A {
public:
B() {}
virtual ~B(){}
int x;
};
int main()
{
A* ptr = new B[5];
delete[] ptr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果删除d'tors,也不例外。预计不会收到异常。
编译器:g++(Ubuntu 11.2.0-19ubuntu1)11.2.0
c++ ×10
delete-operator ×10
new-operator ×2
pointers ×2
arrays ×1
c++11 ×1
destructor ×1
nullptr ×1
private ×1