为啥我在 C++ 中有一个空指针取消引用?

Posted

技术标签:

【中文标题】为啥我在 C++ 中有一个空指针取消引用?【英文标题】:Why do I have a null pointer dereference in C++?为什么我在 C++ 中有一个空指针取消引用? 【发布时间】:2018-09-28 08:29:09 【问题描述】:

我在 Eclipse 中获得了一个空指针取消引用,但我不知道如何实际修复这个错误。

这是日志错误:

04-18 10:27:48.538: A/DEBUG(22481): Build fingerprint: 
'OnePlus/OnePlus3/OnePlus3T:8.0.0/OPR6.170623.013/12041042:user/release- keys'
04-18 10:27:48.538: A/DEBUG(22481): Revision: '0'
04-18 10:27:48.538: A/DEBUG(22481): ABI: 'arm'
04-18 10:27:48.538: A/DEBUG(22481): pid: 22024, tid: 22078, name: GLThread     8317  >>>  <<<
04-18 10:27:48.538: A/DEBUG(22481): signal 11 (SIGSEGV), code 1     (SEGV_MAPERR), fault addr 0x0
04-18 10:27:48.538: A/DEBUG(22481): Cause: null pointer dereference
04-18 10:27:48.538: A/DEBUG(22481):     r0 b9bb0e74  r1 00000000  r2     00000001  r3 00000000
04-18 10:27:48.538: A/DEBUG(22481):     r4 000aa185  r5 afdd0c28  r6     b9bb1a40  r7 b9b83a40
04-18 10:27:48.538: A/DEBUG(22481):     r8 0000cf00  r9 000ac440  sl     00000000  fp 0000ac44
04-18 10:27:48.538: A/DEBUG(22481):     ip 000bdcc0  sp c1bfe1b0  lr     c25fd079  pc c25fd084  cpsr 08070030
04-18 10:27:48.541: A/DEBUG(22481): backtrace:
04-18 10:27:48.541: A/DEBUG(22481):     #00 pc 0022d084      /data/app/com.-xBYgyq_62u2R3qWK0qBgkQ==/lib/arm/libgame.so     (_ZN12CSoundSource12GetAudioDataEPfii+87)

而这部分代码出现了错误:

void CSoundSource::GetAudioData(float *data, int frameStart, int frames)

int i=0;
while(i<frames)
    
    int temp_samp = (frameStart+i) % TotalSamples;
    int tmp_div = temp_samp / blockSize;
    int tmp_mod = temp_samp % blockSize;
        *data = block[tmp_div]->buffer[tmp_mod][0] * 0.00003f;
    data++;
        *data = block[tmp_div]->buffer[tmp_mod][1] * 0.00003f;
    data++;
    i++;
    

有人可以告诉我如何解决 null 取消引用吗?或者给我一个提示以指出正确的方向?

谢谢。

【问题讨论】:

data 的值是多少? block 来自哪里?请构造一个minimal test case。 你有一个空指针?您在显示的代码中取消引用多个指针,它们中的任何一个都可能为空。使用 debugger 在崩溃发生时捕捉崩溃,找到发生崩溃的确切行,并查看哪些指针为空。 留下原始代码的链接。更好的是,改用共享指针和迭代器。或者使用 Try-Catch-Throw 块。 @AniketChowdhury 不要要求提供原始代码的链接。要求minimal reproducible example。我们不想要指向(可能是巨大的)代码转储的链接,我们想要有助于帮助 OP 的东西。制作 MCVE 帮助无数提问者自己突然发现错误。例如,在这种情况下,OP 已经毫无帮助地完全专注于仅显示症状的功能。错误的来源在所示代码之外。但那个“外面”可能很大。理想情况下,我们只想要有错误的部分。 ericlippert.com/2014/03/05/how-to-debug-small-programs ***.com/questions/2069367/how-to-debug-using-gdb ericlippert.com/2014/03/21/find-a-simpler-problem 如果你真的做到了这三个方法并且没有看到你的错误,我支付你的晚餐,只要你来看我。 ;-) 【参考方案1】:

我发现了问题。

显然崩溃是因为block[tmp_div] 为NULL。另一个线程在*data = block[tmp_div]-&gt;buffer[tmp_mod][0] * 0.00003f; 之前没有为其分配值,因此我必须检查每个block[] 以查看它是否为NULL,如果是则尝试再次为其赋予正确的值。

因此我发布的部分代码如下所示:

void CSoundSource::GetAudioData(float *data, int frameStart, int frames)

    int i=0;
    while(i<frames)
    
        int temp_samp = (frameStart+i) % TotalSamples;
        int tmp_div = temp_samp / blockSize;
        int tmp_mod = temp_samp % blockSize;
        if(block[tmp_div])
            *data = block[tmp_div]->buffer[tmp_mod][0] * 0.00003f;
        data++;
        if(block[tmp_div])
            *data = block[tmp_div]->buffer[tmp_mod][1] * 0.00003f;
        data++;
        i++;
    

【讨论】:

多线程可能相当棘手...不要忘记使用Mutexes 来确保一次只有一个线程读取或写入共享资源。

以上是关于为啥我在 C++ 中有一个空指针取消引用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥代码会通过空指针显式调用静态方法?

C:为啥指针地址在函数中设置为空,而在main中有一个非空地址? [复制]

cppcheck 空指针取消引用:m_buffer - 否则检查它是不是为空是多余的

cppcheck 取消引用空指针

条件是多余的,或者可能存在空指针取消引用

cppcheck 空指针取消引用,但它实际上可以变为空