1

我在 Linux 上有一个 C++ 程序,它在一段时间后崩溃并显示以下消息:

*** glibc detected *** free(): invalid pointer: 0x41e0ce94 ***

在程序中,我广泛使用容器。他们必须存储一个简单类的对象。

编辑2009-4-17:

与此同时,很明显该错误与简单类无关。如果我将容器更改为保存其他数据类型,错误仍然会发生。问题一定出在我的代码中的其他地方,我目前正在尝试解决...

4

5 回答 5

4

考虑使用 std::string 来保存字符串值而不是原始 char 指针。这样您就不必担心在分配、复制和销毁方法中管理字符串数据。你的问题很可能就在那里。

编辑:你发布的新类没有问题,如果你只使用 char * 指向字符串常量,第一个版本也没有问题。问题出在程序的其他地方或您使用课程的方式上。您将不得不花更多时间在调试器和/或 valgrind 中进行挖掘以追踪问题。我会弄清楚指定地址所指向的内容,并尝试确定为什么它被释放两次。

于 2009-04-15T14:25:51.787 回答
3

猜测一下,您的复制 ctor、赋值操作或析构函数有问题 - 您需要显示这些代码。

编辑:刚刚注意到你没有赋值运算符 - 假设你的复制构造函数和析构函数没问题,你也需要一个赋值运算符,如 std:; 容器将使用它。

于 2009-04-15T14:22:28.830 回答
1

我一直在与我们正在开发的 C/C++ 应用程序作斗争,我想到的第一个想法是

  • 一个指针已被修改并且它指向一个无效的位置 (ptr++;) 或类似的东西。
  • 您已释放对象,但指针仍保持方向。

    Valgrind之类的工具可以帮助您检测代码中可能存在的错误。安装:

    sudo apt-get install valgrind

    并使用它:

    valgrind --tool=memcheck --leak-check=full ...

    它会在程序运行时报告错误,并在程序结束后给你一个报告。唯一的问题是 valgrind 认为可能的问题可能不是真正的问题。但这是一个起点。

于 2009-04-15T14:34:29.113 回答
1

这肯定是一个错误的字符串值。如果是悬空指针问题,使用 std::string 可能在这方面有所帮助。还要确保所有字符串初始化都按预期工作。

如果我正确理解了该类,则您假设驻留在 m_cstring 中的任何内存都不会在该类的生命周期内被释放。在您的情况下,这也意味着容器的生命周期。检查你的范围。

您可能遇到的另一个问题是,如果您的析构函数正在删除 cstring,那么在构造函数中使用默认值是一个非常糟糕的主意,因为您将尝试解除分配静态分配的 cstring。

可以在 C++ 中定义一个应该返回字符串但不返回任何内容的函数,最终得到一个错误的字符串(通常编译器会捕获“到达非 void 函数的结尾”,但不会总是)。

同上使用 valgrind。

作为阅读各种评论后的附录,程序中其他地方的内存错误总是有可能损坏了其中一个字符串。

编辑4-16

在这一点上,我将验证对象的值在构造/破坏时是否正确形成。(尝试打印它们?)如果一切看起来都不错,您可能需要在代码中的其他地方查看错误。

于 2009-04-15T15:10:30.540 回答
0

你的析构函数里面是什么?可能它没有cstring。如果是这种情况,那么您在实例上共享您的 cstring 指针,然后每个实例释放相同的指针。

于 2009-04-15T14:23:42.433 回答