1

在我的一位同事在我们的项目中提交了一些新功能后,我遇到了这种分段错误。新特性对后面的函数没有影响,只是增加了 QString 参数的大小。经过一些调试,我发现在以下函数返回后发生了分段错误。

我需要知道为什么会发生这种情况以及为什么我的解决方法有效,以及解决方法是否安全?

我必须说以下代码片段适用于我现在安装的旧版 Qt(5.3.1 和 gcc 4.8)(Qt 5.9 和 gcc 7.0)。它也适用于 Debug 而不是 Qt 上的 Release 编译模式。

最后,我不想讨论这种加密方法的有效性,而是标题问题。

函数返回后立即发生崩溃,我不知道为什么。

QString Utility::encrypt(QString text)
{
    QByteArray textUtf8 = text.toUtf8();

    // Convert QString to Char
    const char *srcString = textUtf8.constData();
    char encrypted[ textUtf8.size() ];

    // Copy Char by Char
    strcpy(encrypted,srcString);
    for(int u=0; u<textUtf8.size(); u++ ){
        encrypted[u]++;
    }

    return QString::fromUtf8(encrypted);
}

分段错误的输出是:

*** Error in `/home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree': free(): invalid pointer: 0x0000000001cfc800 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7eff199067e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7eff1990f37a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7eff1991353c]
/home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree[0x40171f]
/home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree[0x401344]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7eff198af830]
/home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree[0x4014b9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:01 2098854                            /home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree
00602000-00603000 r--p 00002000 08:01 2098854                            /home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree
00603000-00604000 rw-p 00003000 08:01 2098854                            /home/user/workspace/build-swFree-Desktop_Qt_5_9_1_GCC_64bit-Release/swFree
01cdd000-01d1f000 rw-p 00000000 00:00 0                                  [heap]
7eff10000000-7eff10021000 rw-p 00000000 00:00 0 
7eff10021000-7eff14000000 ---p 00000000 00:00 0 
7eff162bb000-7eff16594000 r--p 00000000 08:01 2752945                    /usr/lib/locale/locale-archive
7eff16594000-7eff16602000 r-xp 00000000 08:01 529479                     /lib/x86_64-linux-gnu/libpcre.so.3.13.2
7eff16602000-7eff16802000 ---p 0006e000 08:01 529479                     /lib/x86_64-linux-gnu/libpcre.so.3.13.2
7eff16802000-7eff16803000 r--p 0006e000 08:01 529479                     /lib/x86_64-linux-gnu/libpcre.so.3.13.2
7eff16803000-7eff16804000 rw-p 0006f000 08:01 529479                     /lib/x86_64-linux-gnu/libpcre.so.3.13.2
7eff16804000-7eff1690c000 r-xp 00000000 08:01 529373                     /lib/x86_64-linux-gnu/libm-2.23.so
7eff1690c000-7eff16b0b000 ---p 00108000 08:01 529373                     /lib/x86_64-linux-gnu/libm-2.23.so
7eff16b0b000-7eff16b0c000 r--p 00107000 08:01 529373                     /lib/x86_64-linux-gnu/libm-2.23.so
7eff16b0c000-7eff16b0d000 rw-p 00108000 08:01 529373                     /lib/x86_64-linux-gnu/libm-2.23.so
7eff16b0d000-7eff16c1c000 r-xp 00000000 08:01 529394                     /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2
7eff16c1c000-7eff16e1b000 ---p 0010f000 08:01 529394                     /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2
7eff16e1b000-7eff16e1c000 r--p 0010e000 08:01 529394                     /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2
7eff16e1c000-7eff16e1d000 rw-p 0010f000 08:01 529394                     /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2
7eff16e1d000-7eff16e1e000 rw-p 00000000 00:00 0                                                                                                                                                                                                                               
7eff16e1e000-7eff16e1f000 r-xp 00000000 08:01 2763515                    /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0.4800.2                                                                                                                                                 
7eff16e1f000-7eff1701e000 ---p 00001000 08:01 2763515                    /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0.4800.2                                                                                                                                                 
7eff1701e000-7eff1701f000 r--p 00000000 08:01 2763515                    /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0.4800.2                                                                                                                                                 
7eff1701f000-7eff17020000 rw-p 00001000 08:01 2763515                    /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0.4800.2                                                                                                                                                 
7eff17020000-7eff17023000 r-xp 00000000 08:01 529264                     /lib/x86_64-linux-gnu/libdl-2.23.so                                                                                                                                                                  
7eff17023000-7eff17222000 ---p 00003000 08:01 529264                     /lib/x86_64-linux-gnu/libdl-2.23.so                                                                                                                                                                  
7eff17222000-7eff17223000 r--p 00002000 08:01 529264                     /lib/x86_64-linux-gnu/libdl-2.23.so                                                                                                                                                                  
7eff17223000-7eff17224000 rw-p 00003000 08:01 529264                     /lib/x86_64-linux-gnu/libdl-2.23.so                                                                                                                                                                  
7eff17224000-7eff1723d000 r-xp 00000000 08:01 529327                     /lib/x86_64-linux-gnu/libz.so.1.2.8                                                                                                                                                                  
7eff1723d000-7eff1743c000 ---p 00019000 08:01 529327                     /lib/x86_64-linux-gnu/libz.so.1.2.8                                                                                                                                                                  
7eff1743c000-7eff1743d000 r--p 00018000 08:01 529327                     /lib/x86_64-linux-gnu/libz.so.1.2.8                                                                                                                                                                  
7eff1743d000-7eff1743e000 rw-p 00019000 08:01 529327                     /lib/x86_64-linux-gnu/libz.so.1.2.8                                                                                                                                                                  
7eff1743e000-7eff18c21000 r--p 00000000 08:01 2379568                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicudata.so.56.1                                                                                                                                                     
7eff18c21000-7eff18e20000 ---p 017e3000 08:01 2379568                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicudata.so.56.1                                                                                                                                                     
7eff18e20000-7eff18e21000 r--p 017e2000 08:01 2379568                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicudata.so.56.1                                                                                                                                                     
7eff18e21000-7eff18fc6000 r-xp 00000000 08:01 2379575                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicuuc.so.56.1                                                                                                                                                       
7eff18fc6000-7eff191c6000 ---p 001a5000 08:01 2379575                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicuuc.so.56.1                                                                                                                                                       
7eff191c6000-7eff191d6000 r--p 001a5000 08:01 2379575                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicuuc.so.56.1                                                                                                                                                       
7eff191d6000-7eff191d7000 rw-p 001b5000 08:01 2379575                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicuuc.so.56.1                                                                                                                                                       
7eff191d7000-7eff191d9000 rw-p 00000000 00:00 0                                                                                                                                                                                                                               
7eff191d9000-7eff19462000 r-xp 00000000 08:01 2379569                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicui18n.so.56.1                                                                                                                                                     
7eff19462000-7eff19661000 ---p 00289000 08:01 2379569                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicui18n.so.56.1                                                                                                                                                     
7eff19661000-7eff1966f000 r--p 00288000 08:01 2379569                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicui18n.so.56.1                                                                                                                                                     
7eff1966f000-7eff19671000 rw-p 00296000 08:01 2379569                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libicui18n.so.56.1                                                                                                                                                     
7eff19671000-7eff19672000 rw-p 00000000 00:00 0                                                                                                                                                                                                                               
7eff19672000-7eff1968a000 r-xp 00000000 08:01 529099                     /lib/x86_64-linux-gnu/libpthread-2.23.so                                                                                                                                                             
7eff1968a000-7eff19889000 ---p 00018000 08:01 529099                     /lib/x86_64-linux-gnu/libpthread-2.23.so                                                                                                                                                             
7eff19889000-7eff1988a000 r--p 00017000 08:01 529099                     /lib/x86_64-linux-gnu/libpthread-2.23.so                                                                                                                                                             
7eff1988a000-7eff1988b000 rw-p 00018000 08:01 529099                     /lib/x86_64-linux-gnu/libpthread-2.23.so                                                                                                                                                             
7eff1988b000-7eff1988f000 rw-p 00000000 00:00 0                                                                                                                                                                                                                               
7eff1988f000-7eff19a4f000 r-xp 00000000 08:01 529417                     /lib/x86_64-linux-gnu/libc-2.23.so                                                                                                                                                                   
7eff19a4f000-7eff19c4f000 ---p 001c0000 08:01 529417                     /lib/x86_64-linux-gnu/libc-2.23.so                                                                                                                                                                   
7eff19c4f000-7eff19c53000 r--p 001c0000 08:01 529417                     /lib/x86_64-linux-gnu/libc-2.23.so                                                                                                                                                                   
7eff19c53000-7eff19c55000 rw-p 001c4000 08:01 529417                     /lib/x86_64-linux-gnu/libc-2.23.so                                                                                                                                                                   
7eff19c55000-7eff19c59000 rw-p 00000000 00:00 0                                                                                                                                                                                                                               
7eff19c59000-7eff19c6f000 r-xp 00000000 08:01 529390                     /lib/x86_64-linux-gnu/libgcc_s.so.1                                                                                                                                                                  
7eff19c6f000-7eff19e6e000 ---p 00016000 08:01 529390                     /lib/x86_64-linux-gnu/libgcc_s.so.1                                                                                                                                                                  
7eff19e6e000-7eff19e6f000 rw-p 00015000 08:01 529390                     /lib/x86_64-linux-gnu/libgcc_s.so.1                                                                                                                                                                  
7eff19e6f000-7eff19fe1000 r-xp 00000000 08:01 2764170                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21                                                                                                                                                        
7eff19fe1000-7eff1a1e1000 ---p 00172000 08:01 2764170                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21                                                                                                                                                        
7eff1a1e1000-7eff1a1eb000 r--p 00172000 08:01 2764170                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7eff1a1eb000-7eff1a1ed000 rw-p 0017c000 08:01 2764170                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7eff1a1ed000-7eff1a1f1000 rw-p 00000000 00:00 0 
7eff1a1f1000-7eff1a71b000 r-xp 00000000 08:01 2380819                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1
7eff1a71b000-7eff1a91a000 ---p 0052a000 08:01 2380819                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1
7eff1a91a000-7eff1a926000 r--p 00529000 08:01 2380819                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1
7eff1a926000-7eff1a928000 rw-p 00535000 08:01 2380819                    /opt/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1
7eff1a928000-7eff1a92b000 rw-p 00000000 00:00 0 
7eff1a92b000-7eff1a951000 r-xp 00000000 08:01 524312                     /lib/x86_64-linux-gnu/ld-2.23.so
7eff1ab21000-7eff1ab2b000 rw-p 00000000 00:00 0 
7eff1ab4d000-7eff1ab50000 rw-p 00000000 00:00 0 
7eff1ab50000-7eff1ab51000 r--p 00025000 08:01 524312                     /lib/x86_64-linux-gnu/ld-2.23.so
7eff1ab51000-7eff1ab52000 rw-p 00026000 08:01 524312                     /lib/x86_64-linux-gnu/ld-2.23.so
7eff1ab52000-7eff1ab53000 rw-p 00000000 00:00 0 
7ffe006ae000-7ffe006cf000 rw-p 00000000 00:00 0                          [stack]
7ffe006e2000-7ffe006e4000 r--p 00000000 00:00 0                          [vvar]
7ffe006e4000-7ffe006e6000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

我想出的解决方法如下:

char encrypted[ textUtf8.size() + 1 ];

但是,我承认我不知道它为什么起作用。有人可以解释一下吗?

有没有更好的解决方案?

4

2 回答 2

4

问题是返回的 QByteArray 中的数据text.toUtf8()不是 NUL 终止的,并且 strcpy() 需要一个 NUL 终止的字符串......因为它没有得到一个,它会很高兴地继续复制额外的垃圾字节到结束你的encrypted数组,直到它最终在某个地方遇到一个零字节,并破坏你的堆栈,这会导致函数返回时崩溃。

此外,您的encrypted数组不够大,无法容纳strcpy()要放入其中的 NUL 字节。

修复将是这样的:

char encrypted[ textUtf8.size() + 1 ];   // +1 to hold the NUL terminator byte
memcpy(encrypted, srcString, textUtf8.size() );
encrypted[textUtf8.size()] = '\0';  // place NUL-terminator byte
[...]

此外,可移植性说明:动态大小的数组不是 C++ 标准的一部分,因此您的声明char encrypted[ textUtf8.size() + 1];仅适用于您,因为您的编译器包含一个非标准扩展来启用它。如果您希望您的代码是可移植的(因为所有自尊的 Qt 代码都应该是;)),您可能希望使用 std::vector 或其他类似的更高级别机制而不是动态大小的数组。

于 2017-08-04T02:26:34.070 回答
1

字符加密[ textUtf8.size() + 1 ];

由于大小,我们必须使用空字符来终止字符串数组

例如试试这个

#include<iostream>
#include<string>
using namespace std;
int main()
{
    char textUtf8[5] ="hello";  


}

您将看到警告“char 数组的初始化字符串太长”

于 2017-08-04T02:31:18.947 回答