调用空智能指针对象的函数,Windows及Linux行为解析

来源:清泛原创     2020-11-23 17:02:40    人气:     我有话说( 0 人参与)

先看结论:Windows下可以调用空智能指针对象的函数,但是函数中访问目标对象的成员变量会崩溃,this指针为nullptr;Linux下Debug版本及不开优化版本也能正常运行,-O0以上优化版本

先看结论:Windows下可以调用空智能指针对象的函数,但是函数中访问目标对象的成员变量会崩溃,this指针为nullptr;Linux下Debug版本及不开优化版本也能正常运行,-O0以上优化版本访问空智能指针对象函数会发生崩溃。

问题起因:一个智能指针对象使用IsNull()判断是否为空后,执行函数,仅在Linux开优化(-O0以上)发生崩溃,代码如下:

#include <stdio.h>
#include <memory>
#include <assert.h>

class RawValue : public std::enable_shared_from_this<RawValue> {
public:
	bool IsNull() {
		printf("this:%x\n", this);
		return this == nullptr;
	}
	int val_{0};
};
using NValue = std::shared_ptr<RawValue>;

int main() {
	NValue null;
	assert(null == nullptr);
	assert(!null);
	assert(null.get() == nullptr);
	assert(null->IsNull());
	null->IsNull();
	//!!!crash   assert(null->val_ == 0);
	printf("---End---\n");
	return 0;
}

Windows:Debug/Release/优化版本均正常运行。

Linux gcc:Debug/-O0正常运行;-O0以上崩溃。
 

感觉和编译器优化相关,根据反汇编推测如下:
不崩溃场景:调用编译好非虚函数,传this指针,仅仅访问空指针this本身不崩溃,不能访问目标对象实际的成员。
崩溃的场景:函数事先没有加载,需要通过对象指针拿到函数偏移才能调用。

因此,上例中的IsNull的写法不推荐,最好使用if(null)直接判断智能指针是否为空。

shared_ptr nullptr

注:本文为本站或本站会员原创优质内容,版权属于原作者及清泛网所有,
欢迎转载,转载时须注明版权并添加来源链接,谢谢合作! (编辑:admin)
分享到: