在我们的应用程序中,我们会在执行后发现崩溃。堆栈跟踪显示崩溃是由于cpp文件中存在的全局变量。生成的valgrind报告显示无效的空闲/读/写错误,这意味着它正在尝试删除不再有效的内存。
文件:crash.cpp
namespace abc
{
MutexClass obj; //A is a class
// remaining code
ChildClass::ChildClass():Parent(obj){}
}
然后我们将给定变量放在一个未命名的命名空间中,我们不再发生崩溃,而valgrind也没有报告无效的读/写/错误:
档案:nocrash.cpp
namespace
{
MutexClass obj;
}
namespace abc
{
// remaining code
ChildClass::ChildClass():Parent(obj){}
}
以上示例是导致问题的类的精简版本。
我们不确定为什么将变量放在未命名的命名空间中会消除此问题。它会改变清理顺序吗?我们尝试编写简单的代码,但我们观察到的清理顺序对于这两种情况都是相同的。
Mutex对象作为参数传递给基类构造函数。 Mutex对象的唯一目的是在基类构造函数中使用。 Mutex对象不会在代码中的任何其他位置使用。
崩溃的valgrind报告
=============================================== ==
主题1:
读取大小为1
位于0x3A24C08260:pthread_mutex_destroy(在/lib64/libpthread-2.5.so中)
by 0x5ABE3DD:osl_destroyMutex(libuno_sal.so.3)
by 0xECD69D1:osl :: Mutex ::〜Mutex()(mutex.hxx:65)
by 0xEF207F5:__ tcf_0( Dispose.cpp:27 )
by 0x3A24033354:exit(在/lib64/libc-2.5.so中)
by 0x3A2401D97A :(在main下面)(在/lib64/libc-2.5.so中)
地址0xeb6bb88是一个大小为40的块中的16个字节
at 0x4A05B3E:free(vg_replace_malloc.c:323)
by 0x3A24033354:exit(在/lib64/libc-2.5.so中)
by 0x3A2401D97A :(在main下面)(在/lib64/libc-2.5.so中)
无效的4号写入
在0x3A24C08272:pthread_mutex_destroy(在/lib64/libpthread-2.5.so中)
by 0x5ABE3DD:osl_destroyMutex(在libuno_sal.so.3中)
by 0xECD69D1:osl :: Mutex ::〜Mutex()(mutex.hxx:65)
by 0xEF207F5:__ tcf_0( Dispose.cpp:27 )
by 0x3A24033354:exit(在/lib64/libc-2.5.so中)
by 0x3A2401D97A :(在main下面)(在/lib64/libc-2.5.so中)
地址0xeb6bb88是一个大小为40的块中的16个字节
at 0x4A05B3E:free(vg_replace_malloc.c:323)
by 0x3A24033354:exit(在/lib64/libc-2.5.so中)
by 0x3A2401D97A :(在main下面)(在/lib64/libc-2.5.so中)
无效的免费()/删除/删除[]
at 0x4A05B3E:free(vg_replace_malloc.c:323)
by 0xECD69D1:osl :: Mutex ::〜Mutex()(mutex.hxx:65)
by 0xEF207F5:__ tcf_0( Dispose.cpp:27 )
by 0x3A24033354:exit(在/lib64/libc-2.5.so中)
by 0x3A2401D97A :(在main下面)(在/lib64/libc-2.5.so中)
地址0xeb6bb78是一个大小为40的块中的0字节
at 0x4A05B3E:free(vg_replace_malloc.c:323)
by 0x3A24033354:exit(在/lib64/libc-2.5.so中)
by 0x3A2401D97A :(在main下面)(在/lib64/libc-2.5.so中)
=============================================== ==
Dispose.cpp:27行定义了互斥变量。
我们希望得到有关此事的任何帮助
谢谢,
萨迪普
答案 0 :(得分:2)
检查您的其他文件。您可能在命名空间abc中有另一个名为obj的全局变量。更改为未命名的命名空间与C中的静态具有相同的效果,这避免了名称冲突(如果这是可能的,任何其他与abc不同的命名空间也将停止该问题)。这种错误通常会导致链接错误,但有时会发生奇怪的事情。
请注意,其他文件不会使用的全局变量应位于未命名的命名空间中,以避免名称冲突。
答案 1 :(得分:0)
您向我们展示的代码没有任何问题。
问题可能在于课程A
?
答案 2 :(得分:0)
您的变量是否使用带有起始下划线的名称?
如果是这种情况,那么你发现麻烦是正常的。
具有初始下划线的全局名称是保留的,不应使用。也可以是带有初始下划线的名称,后跟任何上下文中的大写字母,或带有多个连续下划线的名称。
这是一条规则,由于我不理解的原因经常被许多程序员打破,只是为了这样做的乐趣......
答案 3 :(得分:0)
像你一样移动代码将相对于同一翻译单元中的其他全局变量重新排序A
的构造和销毁。如果您之前创建了A,则稍后将删除它。 (LIFO原则)。其他对象现在可以依赖A
。检查以前在 A
之前创建的对象,以及A
之后的。