C++ 类中的指针越来越乱

Posted

技术标签:

【中文标题】C++ 类中的指针越来越乱【英文标题】:Pointers in C++ Class are getting scrambled 【发布时间】:2011-10-26 14:32:02 【问题描述】:

我现在有很多让我发疯的代码。 我正在使用 OpenGL,构建一个使用几种不同类型对象的 GUI 框架。我有 Image 类,它们加载 *.png 文件并以 GLuint 纹理参考的形式存储图像信息。我有 Panel 和 Button 类,它们带有指向它们应该显示的图像类的指针。我有一个带有面板和按钮指针的 std::vectors 的 Hud 类。最后,我有一个 Engine 类,它包含一个 Hud 类、我所有的 Button 和 Panel 类以及 Image 指针。运行构造函数时,每个 Image 指针都使用以下方法初始化:

imgMy = new Image;

所有图像都初始化后,我运行加载函数:

imgMy->loadImage("imgMy.png");

当然,我在关闭程序时会删除图像。

我的问题是某些图像“越界”了。我现在有大约 30 张图片,其中一些按钮显然指向了错误的图片。我已经彻底检查了我的代码,它看起来很可靠。我相信这是一个内存错误,因为显示不正确图像的按钮不一致。有时它们显示正确的图像,有时不同的按钮显示错误的图像。我希望我能在这里展示我的代码,但它非常庞大。

我在我的 Engine 类中使用 Image 指针而不是实际的 Image 对象的原因是,如果调整 Engine 类的大小或重新排列其内存,我担心 Buttons 指向无效内存。我怀疑对于我想要完成的工作有更好的方法,如果有任何建议,我将不胜感激。

【问题讨论】:

也许你可以在一个重复问题的小例子中使用你的代码的一些 sn-ps 并发布。该练习本身可能会帮助您解决问题 =) 只是一个想法。 描述您的代码所做的工作几乎没有为诊断错误提供依据。您正在描述您认为代码应该做什么,但很明显没有做您认为它做或希望它做的事情。就您对 Engine 类被调整大小或其内存重新排列的恐惧而言,至少在我编程时,我比编译器更经常犯错误。我只会使用对象,并且仅在/如果确实需要时才切换到指针。 信息太少,可能是很多原因造成的。 【参考方案1】:

使用一个调试器,让您在相关的imgMys 上放置一个观察点,然后调试器会告诉您它们在哪里被修改。这可能是追踪它的最简单方法。

您可能还想尝试 valgrind,但这听起来不像 valgrind 会发现的问题类型。

【讨论】:

【参考方案2】:

首先,您不应该在没有充分理由的情况下使用两阶段初始化。这不是一个很好的理由。在构造函数中传递文件名。此外,请始终使用智能指针。

您可以简单地使用const 来强制执行它。

class Button 
    const std::unique_ptr<Image> img;
public:
    Button(std::string filename)
        : img(new Image(filename)) 
;

其次,我不太了解您的首要架构,因为您没有详细描述它,但我不确定这里是否需要 new

【讨论】:

按值 filename 参数是否有原因或者是错字? @Christian:嗯?无论如何,编译器可能会为所欲为。 我知道编译器很聪明,但我们不应该比我们更笨。我的意思是,我不是在谈论使用移位进行整数乘法,而是将重对象作为 const 引用传递,这是一个标准的习惯用法,不应该只是盲目依赖编译器的智能。我知道在某些情况下,按值实际上可以为智能编译器启用更优化的代码并且不会对不太智能的编译器造成任何伤害。如果这是其中一种情况并且我看不到它,那么解释会很好。否则我不会鼓励过度混淆,这不是 Java。 @Christian:类中的一个std::string 将被初始化一次并在应用程序的整个生命周期中保持,这不是一个沉重的对象。在这里引用是一个微优化。 如果它不花费你任何努力(不,我不考虑 7 个字母的努力)并且没有' t 混淆代码或其意图(我认为 const 引用不会)。但是好吧,这可能有点主观,你真的认为 const 引用违反了这些规则。【参考方案3】:

听起来像是内存损坏。您应该考虑使用一些内存调试器,例如valgrind 或some other alternative。如果您在使用指针时遇到任何问题,这些工具将帮助您找到它们。

【讨论】:

【参考方案4】:

我怀疑您以某种方式保留了按钮引用列表和图像引用列表,并且它们并不总是以相同的顺序创建,因此交叉图像。

严格来说,您应该按顺序创建按钮和图像,在创建时分配图像文件。

【讨论】:

以上是关于C++ 类中的指针越来越乱的主要内容,如果未能解决你的问题,请参考以下文章

C++学习 之 类中的特殊函数和this指针

C++中的指针数组

如何在封装在类中的回调函数上发送指针

C++ 类中的const关键字

未定义符号,使用指针 C++ 访问成员函数

Python C Api 和正确处理 C++ 类中的内存