LINUX.ORG.RU

Почему падает программа?

 , ,


0

3
#include <QtCore>

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    qDebug() << QCoreApplication::arguments() << "ARG(2):" << QCoreApplication::arguments().at(2);

    const QString &arg = QCoreApplication::arguments().at(2);

    // ТУТ ПАДАЕМ
    qDebug() << arg;

    return 0;
}



Запускаем:

# ./prog 111111111111111111111111111111111111111 22222222222222222222222222222222222222222222
("./prog", "111111111111111111111111111111111111111", "22222222222222222222222222222222222222222222") ARG(2): "22222222222222222222222222222222222222222222"
Aborted (core dumped)


Ubuntu 16.04. С системным Qt 4.8 получается Aborted. С предкомпилированным Qt 5.8.0 с сайта qt.io вместо Aborted выводится или пустая строка или набор иероглифов в зависимости от длины переданных аргументов. На Windows c Qt 5.8.0/MinGW программа тоже падает.

★★★

Последнее исправление: former_anonymous (всего исправлений: 4)

Посмотри стек вызовов в корке, там и увидишь, почему падает.

alexku
()
Ответ на: комментарий от alexku

Убери ссылку в объявлении arg

Зачем? const ссылка на временный объект позволяет создавать алиасы на временные объекты. При этом временный объект будет разрушен только тогда, когда ссылка уйдёт за scope.

former_anonymous ★★★
() автор топика

Backtrace c qt4:

#0  0x00007ffff6fb8428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007ffff6fba02a in __GI_abort () at abort.c:89
#2  0x00007ffff6ffa7ea in __libc_message (do_abort=2, fmt=fmt@entry=0x7ffff71132e0 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff7001643 in malloc_printerr (ar_ptr=0x7ffff7346b20 <main_arena>, ptr=0x6390b0, str=0x7ffff7110095 "corrupted double-linked list", action=<optimized out>) at malloc.c:5004
#4  malloc_consolidate (av=av@entry=0x7ffff7346b20 <main_arena>) at malloc.c:4173
#5  0x00007ffff70043be in _int_malloc (av=av@entry=0x7ffff7346b20 <main_arena>, bytes=bytes@entry=16777217) at malloc.c:3448
#6  0x00007ffff7005850 in _int_realloc (av=av@entry=0x7ffff7346b20 <main_arena>, oldp=oldp@entry=0x638ae0, oldsize=oldsize@entry=48, nb=nb@entry=16777232) at malloc.c:4302
#7  0x00007ffff7006c89 in __GI___libc_realloc (oldmem=0x638af0, bytes=16777216) at malloc.c:3043
#8  0x00007ffff79aeb60 in QString::realloc (this=this@entry=0x638e70, alloc=8388592) at tools/qstring.cpp:1370
#9  0x00007ffff79b2403 in QString::append (this=0x638e70, str=...) at tools/qstring.cpp:1587
#10 0x00007ffff7a0c42d in QTextStreamPrivate::write (data=..., this=0x639540) at io/qtextstream.cpp:920
#11 QTextStreamPrivate::putString (number=false, s=..., this=0x639540) at io/qtextstream.cpp:1000
#12 QTextStream::operator<< (this=0x638e60, string=...) at io/qtextstream.cpp:2533
#13 0x00000000004016de in QDebug::operator<< (this=0x7fffffffdec0, t=...) at /usr/include/qt4/QtCore/qdebug.h:112
#14 0x000000000040101d in main (argc=3, argv=0x7fffffffdfe8) at main.cpp:11

former_anonymous ★★★
() автор топика
Ответ на: комментарий от former_anonymous

Это так работает для константной ссылки на временный объект. В твоем случае получается просто висячая ссылка на данные разрушенного объекта.

four_str_sam
()
Ответ на: комментарий от former_anonymous

При этом временный объект будет разрушен только тогда, когда ссылка уйдёт за scope.

Ты только не учёл, что scope временного объекта - текущий оператор. Вот если бы ты сделал так

 qDebug() << QCoreApplication::arguments().at(2); 
то у тебя всё отработало бы штатно. А const тут не при делах. Это уже другая опера.

alexku
()
Ответ на: комментарий от former_anonymous

что является временным объектом, нет?

*ВРЕМЕННЫМ* - у тебя объект, на который ты взял ссылку, сдыхает.

Norgat ★★★★★
()
Ответ на: комментарий от alexku

Ты только не учёл, что scope временного объекта - текущий оператор.

только если на него не привязывается ссылка! Какой scope у этого временного объекта?

const QStringList &args = QCoreApplication::arguments();


очевидно, что НЕ текущий оператор, а scope ссылки. Я начинаю понимать, что С++ позволяет только один уровень «временности». То есть создание ссылкы на a().b().c() уже будет неверным решением. Страуструп почему-то об этом умолчал.

former_anonymous ★★★
() автор топика
Последнее исправление: former_anonymous (всего исправлений: 1)
17 августа 2017 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.