前景:在写Qt桌面应用时,有一个场景是TabWidget管理四个子窗口,每个子窗口都只能有一个实例方便窗口的切换,自然而然就想到要用
singleton-pattern
,我应用时能正常启动,但是关闭main window的时候每次都弹出_CrtIsValidHeapPointer(block) …
既然是关闭窗口的时候弹出的错误,那么肯定是
main window
析构的时候发生了错误,根据错误信息也能知道是堆内存中出错了。
当时我的单例模式是这么写的(参考了scott meyers的版本):
class ConfParas : public QWidget
Q_OBJECT
public:
static ConfParas* getInstance()
static ConfParas theConfParas;
return &theConfParas;
explicit ConfParas(QWidget *parent = 0);
ConfParas(const ConfParas&)=delete;
ConfParas& operator=(const ConfParas&)=delete;
自以为没毛病… static
修饰theConfParas
,只会在第一次调用getInstance
方法的时候生成,然后每次返回地址就好了,不需要纯指针版本的if(!theConfParas)
判断语句。
但是任凭我怎么修改代码都不能消除这个error,后来结合文档才找到了原因,这和Qt
本身的框架设计有关。
当有一个指针指向QObject
对象时,Qt
就会接管这个指针,负责它的生命周期。Qt
会默认此指针是动态申请的,所以内存被分配在堆上,并且在合适的时候调用delete
删除此指针。
在我这个版本的getInstance()
中,theConfParas
由于是静态对象,所以是分配在栈上的,在运行时(run time)被管理。而当我将此地址通过return &theConfParas;
传递给一个QObject
对象,即ConfParas
类时,转移权就交给了Qt
。
我们都知道在C++中,static
对象是整个程序生命周期内最后被析构的,而我这个theConfParas
的控制权已经交给了Qt
,Qt
会在合适的时候delete
它,但是主程序并不知道,所以当Mainwindow
退出时,会对它控制范围内的QObject
对象做一个内存回收,这之后C++的内存回收机制又会对static
对象做一次内存回收,这里就出现了double-delete
,’theConfParas’的地址被删除两次,造成了_CrtIsValidHeapPointer(block)
错误。
当我用经典的单例模式写法,这样的问题就解决了…
所以年轻人啊,不要追求什么极简巧妙,runnable
才是王道呀。
所以程序作如下变动:
class ConfParas : public QWidget
Q_OBJECT
public:
static ConfParas* getInstance()
if (!theConfParas)
theConfParas = new ConfParas();
return theConfParas;
explicit ConfParas(QWidget *parent = 0);
ConfParas(const ConfParas&)=delete;
ConfParas& operator=(const ConfParas&)=delete;
private:
static ConfParas *theConfParas;
如果一开始就将它作为QObject
的属性,那么它的生命周期一开始就会交由Qt
管理,就不会发生以上的问题。
其实当_CrtIsValidHeapPointer(block)
错误发生时,我们就应该非常小心了,在堆内存上发生的错误,一定都不是小错误,double-delete
可以说是很严重的错误了(默泪),所以一定要好好排错。
在使用其他框架时,也应该优先去查询对应类目的文档,一个成熟的框架其官方文档一定是详尽的。
前景:在写Qt桌面应用时,有一个场景是TabWidget管理四个子窗口,每个子窗口都只能有一个实例方便窗口的切换,自然而然就想到要用singleton-pattern,但是我应用时能正常启动,但是关闭main window的时候每次都弹出_CrtIsValidHeapPointer(block) …既然是关闭窗口的时候弹出的错误,那么肯定是main window析构的时候发生了错误,根据错误信息也
记录Expression: _CrtisvalidHeapPointer(block) 发生问题。
目前我出现这种情况是我 delete 一个指针, 但是该指针不是指向堆上内存, 编译的时候弹出这种错误。
int d = 10;
int *p = &d;
delete p;
_
CrtIsValidHeapPointer(
block)内存
错误
今天写代码
时VS2019报了_
CrtIsValidHeapPointer(
block)的
错误
查阅资料后发现是因为
delete时,目标指针的指向中途发生了改变,
导致错误。
一
时找不到两全其美的办法,既不报错,又能释放正确的堆内存。
但俗话说的好,解决不了问题,就解决提出问题的人,所以我就把
delete那行代码删掉了。
成功解决!!!
hhhhh,如果有小伙伴找到两全其美的办法可以告诉我,在此谢过。
在嵌入式里面遇到 free(): invalid pointer
结论:函数有返回类型,但是却没有返回值。在有些机器里面会导致这个问题。
一开始我以为是哪里内存有问题。但我仔细看了当下,都没释放内存。
我是这样写的:
在hideTopBottomWidget函数里面调用完start之后挂掉的(开始有在start后面打印的,打印也打印出来了。我以为是调用了start之后他做了什么释放内存的操作。)
后面我百思不得其解,不用函数了,直接调用变量。
没想到居然过了!没死机了!我就觉得很离谱。我函数有问题
1问题描述
我用Qt Creator在ubuntu下面编译了一个dll(姑且称为a.dll)吧,和一个exe(姑且程序b.exe)吧,运行是好好的。
但是迁移代码到windows上面的时候编译也正常,但是在我关闭窗口的时候,程序断点在delete语句处,并出现了下图的错误。
然后我在C::\下搜索dbgheap.c文件,最终dbgheap.c文件的的路径是(C:\Program Fi