У меня ошибка сегментации после того, как мой коллега добавил в наш проект несколько новых функций. Новая функция не влияет на следующую функцию, а только увеличивает размер аргумента QString.
После некоторой отладки я выяснил, что ошибка сегментации происходит после возврата следующей функции.
Мне нужно знать, почему это происходит, и почему мой обходной путь работал, и если обходной путь безопасен?
Я должен сказать, что следующий фрагмент работает на более старой версии Qt (5.3.1 с gcc 4.8), которую я сейчас установил (Qt 5.9 с gcc 7.0).
Он также хорошо работает в Debug, а не в режиме компиляции Release в Qt.
Наконец, я не хочу обсуждать эффективность этого метода шифрования, но озаглавленную проблему.
Сбои происходят сразу после возврата функции, я понятия не имею, почему.
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 ];
Однако, признаюсь, я не знаю, почему это сработало. Может кто-нибудь объяснить это?
Есть ли лучшее решение?
Проблема в том, что данные в QByteArray возвращаются text.toUtf8()
не завершается NUL, и strcpy () ожидает строку с NUL-завершением … так как она не получает ее, она с радостью продолжит копировать дополнительные байты мусора после окончания вашего encrypted
массив, пока он, наконец, не встретит где-нибудь нулевой байт и не повредит ваш стек, что приводит к падению, когда функция возвращается.
Кроме того, ваш encrypted
массив не достаточно велик, чтобы содержать NUL-байт, strcpy()
хочет разместить в нем.
Исправление будет что-то вроде этого:
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 или другой аналогичный механизм более высокого уровня вместо динамически изменяемого массива.
символ шифруется [textUtf8.size () + 1];
Из-за размера мы должны использовать нулевой символ для завершения массива строк
Например попробуйте это
#include<iostream>
#include<string>
using namespace std;
int main()
{
char textUtf8[5] ="hello";}
Вы увидите предупреждение «Строка инициализатора для массива char слишком длинная»