什么负责删除我的指针
What is responsible for deleting my pointer?
我经常想知道,
我知道我可以创建一个指向对象实例的指针,同时使用 new
关键字将该指针作为参数传递给函数。就像我在下面的 Animation::newFrame
函数中所做的那样,在下面的示例中给出。
但是,我也知道,作为一般规则,我负责调用delete
我使用 new
创建的东西。
因此,当我像这样调用 frame 的构造函数时:
Frame* myFrame
= new Frame(new point(0,0), new point(100,100), new point(50,20));
最终为我在上述函数调用中使用new
创建的 3 个点释放内存的责任在哪里?
毕竟,以上3个新点并没有完全让我delete
的名字。
我一直假设它们属于调用它们的函数的范围,并且它们只会超出函数的范围。然而,最近我一直在想也许事实并非如此。
我希望我在这里已经足够清楚了。
提前感谢,
家伙
struct Frame
{
public:
point f_loc;
point f_dim;
point f_anchor;
//the main constructor:: Creates a frame with some specified values
Frame(point* loc, point* dim, point* anchor)
{
f_loc = loc;
f_dim = dim;
f_anchor = anchor;
}
};
struct Animation
{
public:
vector<Frame*> frameList;
//currFrame will always be >0 so we subtract 1
void Animation::newFrame(int &currFrame)
{
vector<Frame*>::iterator it;//create a new iterator
it = frameList.begin()+((int)currFrame);//that new iterator is
//add in a default frame after the current frame
frameList.insert(
it,
new Frame(
new point(0,0),
new point(100,100),
new point(50,20)));
currFrame++;//we are now working on the new Frame
}
//The default constructor for animation.
//Will create a new instance with a single empty frame
Animation(int &currFrame)
{
frameList.push_back(new Frame(
new point(0,0),
new point(0,0),
new point(0,0)));
currFrame = 1;
}
};
编辑:我忘了提到这个问题纯粹是理论上的。我知道有更好的替代原始指针,例如智能指针。我只是要求加深我对常规指针以及如何管理它们的理解。
此外,上面的例子取自我的一个项目,该项目实际上是 C++/cli 和 c++ 混合的(托管和非托管类(,所以这就是为什么构造器只接受point*
而不是按值传递(point
(。因为point
是一个非托管结构,因此在托管代码中使用时,必须由我自己(程序员(管理。:)
澄清并通常强制执行资源所有权的语义是程序员的责任。 这可能是一件棘手的事情,尤其是在处理原始指针时,在资源所有权尚未得到任何实际设计考虑的环境中。 后者不仅在菜鸟程序员编写的玩具程序中很普遍,而且在具有数十年经验的人编写的生产系统中也很普遍,他们应该更了解。
在上面的实际案例中,Frame
对象本身必须负责delete
传入的 3 个指针,而Frame
本身必须负责delete
该指针。
由于资源所有权是一个雷区,程序员很久以前就发明了许多技术来澄清所有权的语义,并使粗心的程序员更难引入错误和泄漏。 如今,C++人们认为最佳做法是尽可能避免原始指针,事实上,完全避免动态分配 - 这在很大程度上是因为资源所有权是一个如此危险的雷区。
在C++中,用于实现这些目标的主要习语是RAII,使用的主要工具是auto_ptr
(C++03(,unique_ptr
,shared_ptr
及其同类。 Boost还提供了许多所谓的"智能指针"。 其中许多与 C++11 中的指针相似(事实上,C++11 中的新智能指针是由 Boost 初始开发的(,但也有一些超越了,例如 intrusive_ptr
.
首先,需要修复代码以使其编译 - 例如,您可能无法将point*
分配给point
(取决于point
的实现(。
完成此操作后,问题的答案是Animation
需要释放其frameList
中的所有内容,并且Frame
将需要释放传递的point*
秒。
一个更好的答案(虽然不是你所要求的(是你应该使用shared_ptr
或unique_ptr
来管理内存 - 这些将为你删除指向的对象。这绝对是我会为frameList
做的 - 让它成为std::vector<std::shared_ptr<Frame>>
.
在这种情况下,可能没有充分的理由将指针用于 point
s(我猜它们只是坐标,复制起来非常便宜( - 我只是通过值或常量引用传递它们。这样就不涉及堆分配,而且要简单得多。
垃圾回收器,智能指针,有时它是自动的(如果您从堆栈中分配(。基本上,负责的是你,但你可以把责任委托给其他地方。
如果您调用的函数没有明确声明它将获得传递的指针的所有权,delete
完成后对其进行处理,则您有责任delete
您自己new
的任何内容。
正如我从您的代码片段中看到的那样,当前的内存策略是"传递所有权"。 例如,您创建 3 个点实例,然后将它们传递给 Frame 构造函数 - 从这一刻起,Frame 实例负责管理这 3 个点内存。因此,这意味着您必须为 Frame 类提供一个析构函数,该析构函数将负责删除存储为成员的 3 个点中的每一个点的内存。
以上所有内容都是关于"原始记忆"技术,这不是必要的新星日。请改用智能指针。例如,std::auto_ptr 在这里是一个很好的候选者(但请注意一些陷阱:如果您将一个auto_ptr复制到另一个,源将被清除为 NULL,目标将拥有内存(。这里另一个广泛分布的候选者是 boost::shared_ptr(它甚至作为 tr1:: 命名空间的一部分包含在最新的 C++ 标准中(。并且不要忘记:您必须了解用于您选择的智能指针的内存策略。否则,您最终将与被摧毁的实例的幽灵交谈,或者您的实例将永远不会像瓶子里的精灵一样被释放。
这在很大程度上取决于约定。 这看起来像是GUI,GUI 中的通常约定是包含对象一旦对delete
负责已传递指针。 因此,Animation
会delete
frameList
的所有指针都在其析构函数中,以及 Frame
将删除它在其析构函数中保存的任何指针。(请注意,此约定非常特定于 GUI,但是,在大多数其他情况下,其他公约将是用过的。
话虽如此,对于一个价值来说,C++也是非常不典型的就像Point
要动态分配一样,以及也不会有指向他们的指针。
抱歉,没有完全阅读。您有责任删除刚刚创建的对象,如果您没有对点的引用,则应在框架对象中创建析构函数。http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr380.htm
class X {
public:
// Constructor for class X
X();
// Destructor for class X
~X();
};
X::~X(( 在 X 对象删除时自动调用。
如果我错了,请纠正我。
- C++为什么我的指针选择排序中存在分段错误?
- 指针相关的UE4崩溃.我的指针哪里错了?
- 为什么我的指针数组分配不起作用
- 为什么我的指针不是结构或联合?
- 如果我不使用 vector.reserve(),为什么我的指针会失效?
- 为什么我的指针会导致段错误
- 我的指针代码 c++ 中的分段错误(核心转储)
- 如何在我的指针和阵列功能中修复未解决的外部错误-LNK2019和LNK1120
- 在C++和Windows中如何处理我的指针
- C 多重继承 - 编译器修改我的指针
- 为什么我的指针在 main 中取消引用后具有不同的值,而不是在我自己的自定义函数中取消引用它时?
- 无法让我的指针发送对数组的引用
- 为什么我的指针出现分段错误
- 保证我的指针内存容器稍后存在
- C++ LP64 中通过引用更改我的指针值传递.我应该看什么
- 什么负责删除我的指针
- 我的指针有什么问题(open_stackdumpfile错误)?
- 为什么我的指针输出的是字符串,而不是C++中的内存地址
- 为什么我的指针会自动改变
- 试图创建一个程序来读取用户输入,然后将数组分解为单独的单词,我的指针都有效吗