从堆栈中手动删除对象是否是错误/非法的C++,或者有可接受的情况?
编辑
Constructor(pointer parent, pointer left, pointer right):parent_(parent),left_(left), right_(right)
{ }
~Constructor()
{
delete parent_;
delete left_;
delete right_;
}
main()
{
Object parent;
Object left;
Object right;
Constructor c(&parent,&left,&right);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法检查对象是在堆上还是堆栈上?
我有一个带有Node的LinkedList,它有一个字段:
void* _data;
Run Code Online (Sandbox Code Playgroud)
现在,我想删除这些数据,但我不知道数据是原始的还是动态分配的对象.
所以,如果写:
~Node() {
delete _node;
}
Run Code Online (Sandbox Code Playgroud)
并且数据是动态分配的对象,它会调用对象的析构函数还是会有内存泄漏?
那我怎么能做这个呢?
这是一个非常简单的问题(或至少乍一看).让我们说我们有以下程序:
void procedure(void)
{
int x = new int;
x=42;
}
Run Code Online (Sandbox Code Playgroud)
当我在我的程序中调用此过程时,它应该导致所谓的内存泄漏,对吧?我在处理一个小项目时遇到了这样的错误,然后编译器输出了类似于:检测到的内存泄漏.转储内存块. ..现在我尝试模拟内存泄漏并查看编译器输出但它根本没有抱怨(我使用Visual Studio).
真的是内存泄漏是我的问题.
哪个代码好(如果好的话)
void DeleteObject(Object* obj)
{
delete obj;
}
Run Code Online (Sandbox Code Playgroud)
要么
void DeleteObject(Object** obj)
{
delete *obj;
}
int main()
{
Object *obj = new Object();
DeleteObject(&obj); or DeleteObject(obj);
}
Run Code Online (Sandbox Code Playgroud)
实际上DeleteObject功能不是那么短(它删除了对象字段).
以下是从单个链接列表尾部删除元素的代码的一部分:
int SLList::deleteFromTail()
{
int el = tail->info;
//if the list has only one element
if(head == tail) {
delete head;
head = tail = 0;
}
else {
//some code here...
}
return el
}
Run Code Online (Sandbox Code Playgroud)
这里head和tail是指向LL的第一和最后一个元素,分别.
在我们设置if之后的上面的块delete head中head = tail = 0.
但是在我们删除之后,我们head如何才能将它的价值设定为某种东西?(NULL在这种情况下)
这是代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
int *p = new int[2];
p[0] = 1;
p[1] = 2;
cout << *p++ << endl;
delete p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它可以编译,但得到一个运行时错误"free():无效指针",后跟一个内存映射.
操作系统ubuntu 10.10
编译器:g ++ 4.4.3
考虑这个程序:
#include <iostream>
int main()
{
delete std::cout;
}
Run Code Online (Sandbox Code Playgroud)
AFAIK转换函数operator void*()const已从C++ 11中删除.因此,该程序在C++ 11编译器上的编译失败.雅,这是真的,g ++ 4.8.1和4.9.2都给出了诊断(以警告的形式,删除void*未定义,这也是好事).但是这个程序不应该在编译时失败,因为删除了转换函数,因为在C++ 98和C++ 03中,所有流对象都可以隐式转换为void*.这个错误吗?他们仍然没有实施这一改变似乎有点令人惊讶.
我在g ++ 4.9.2(支持C++ 14)中尝试过这个程序,但是它提供了警告而不是编译器错误.Ideone编译器按预期给出了错误.(在这里查看现场演示)
我刚遇到一个关于指针的小问题.因为我希望能够快速简便地在一行中执行此任务:
...
delete pointer;
pointer = 0;
...
Run Code Online (Sandbox Code Playgroud)
我只是快速设置一个简单的头文件,其模板方法接受任何类型的指针.它看起来像这样:
#ifndef P_DELETE_H
#define P_DELETE_H
template <typename T>
void pDelete(T* pointer) {
if (pointer) {
delete pointer;
pointer = 0;
}
}
#endif
Run Code Online (Sandbox Code Playgroud)
但是,结果不符合我对删除对象和指针重置的期望.相反,似乎只删除了对象,但将其设置为零没有效果(这是我需要的).如果这里的某些人可以让我稍微放松一下并解释这种行为,那我就会大惊小怪!
更新:
正如答案所解释的那样,使用std :: unique_ptr和std :: shared_ptr比使这个指针无效更安全.
但是如果你真的需要按照我的要求去做,下面的代码就可以了:
template <typename T>
inline void pDelete(T*& pointer) {
if (pointer) {
delete pointer;
pointer = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这通常是不安全的,即使它正确地删除并取消所有实例上的指针(快速测试显示这一点).
感谢大家提供的信息丰富的答案!
我有一些遗留代码,其中动态分配对象然后发出:
QList<MyClass *> *list = new QList<MyClass *>();
...
emit listReady(*row);
void OtherClass::slotList(QList<MyClass> list) {
...
delete list???
}
Run Code Online (Sandbox Code Playgroud)
我可以删除列表中的对象,我可以清除列表,是否可以删除我在插槽中的列表?
看看这个cplusplus.com时间示例,让我更多地思考指针.代码没有delete(也没有new).
警告:我一般尽量避免使用指针,所以我绝对不会精通.
我从下面的例子中删除了很多代码,以便专注于我的问题:
/* time example */
#include <stdio.h> /* printf */
#include <time.h> /* time_t, struct tm, difftime, time, mktime */
int main ()
{
time_t timer;
time(&timer); /* get current time; same as: timer = time(NULL) */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我应该在此结束时删除计时器,还是只是指向系统资源?我的理解是每当我使用时new,我都应该使用delete.认为我没有使用是不对的new,我不需要delete.
这个堆栈问题似乎是我正在寻找和解释我不需要delete(它匹配网站上的示例代码),因为我没有做new; 但是,我不确定我使用的函数是不是在new某个地方调用(因为我发现它很难读取源代码).我怎么知道?我需要知道吗?
我真的很讨厌使用这个旧的时间代码,不能等待即将到来的C++ 20 chrono更新,但这对我的项目来说太遥远了.
c++ ×10
delete-operator ×10
pointers ×4
cout ×1
destructor ×1
dump ×1
function ×1
g++ ×1
linked-list ×1
memory ×1
memory-leaks ×1
object ×1
qt ×1
templates ×1
time ×1