C++中检查变量是否为nullptr为何触发访问违例错误?
C++中检查指针是否为nullptr触发访问违例异常的问题分析
问题背景
本人主要是C#开发者,偶尔使用C++,遇到一个难以理解的问题:
在类的头文件中定义了FFmpeg相关成员变量:
AVFormatContext* formatContext = nullptr;
在类的析构函数中通过以下代码检查该对象是否为nullptr:
if(formatContext != nullptr) avformat_close_input(&formatContext);
但执行if判断时触发了如下异常:
Invalid argumentException thrown at 0x00007FFEA696920A (avformat-60.dll) in Blabla.exe: 0xC0000005: Access violation reading location 0x0000000
疑惑点:为何在C++中仅仅检查指针是否为nullptr会触发此类异常?并未尝试使用对象,只是检查地址是否为nullptr,也未验证对象的有效性。感觉指针被篡改了,但这可能吗?
补充说明
使用C++17,相关操作均为FFmpeg库调用,请问下述分析思路是否正确?
AVFormatContext* formatContext = nullptr; // formatContext正常初始化为nullptr ... avformat_fill_the_context_(&formatContext) //formatContext被填充,不再为nullptr,指向有效对象 ... av_do_somestuff(formatContext) //某个调用篡改了指针 ... if(formatContext != nullptr) //此处触发异常,但指针早已被篡改
这个分析逻辑是否正确?这类情况是否会发生?
解答
你的分析逻辑是完全正确的,这类情况确实会发生,具体原因和排查方向如下:
指针被非法篡改是核心原因
FFmpeg的部分函数如果使用不当(比如传入错误参数、内存越界、重复释放等),可能会意外修改formatContext指针变量本身的内存值。比如某函数内部存在内存越界操作,刚好覆盖了formatContext所在的内存区域,就会导致指针值变成非法地址(比如0x0000000附近的无效地址)。异常的本质
你看到的异常提示是“Access violation reading location 0x0000000”,说明程序尝试读取地址0x0000000的内存——这个地址属于系统保留的无效区域。这种情况大概率是formatContext指针变量本身的内存被破坏,导致读取它的值时实际访问了无效地址,而非单纯指针指向nullptr。排查方向
- 在关键步骤(调用FFmpeg函数前后)打印
formatContext的地址值,确认是否在某个调用后指针值发生异常变化; - 检查是否存在重复释放
formatContext的情况:比如调用avformat_close_input后未将指针置为nullptr,后续析构函数再次检查时,指针已变成野指针; - 验证FFmpeg函数的调用参数是否正确:比如是否传入错误的指针地址、多线程环境下是否未正确同步导致内存竞争。
- 在关键步骤(调用FFmpeg函数前后)打印
内容的提问来源于stack exchange,提问作者IvanGrozny
相关产品推荐
相关产品推荐

