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

清泛原创
先看结论: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

分享到:
评论加载中,请稍后...
创APP如搭积木 - 创意无限,梦想即时!
回到顶部