Russian Qt Forum
Ноябрь 23, 2024, 15:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 3 [4] 5 6 7   Вниз
  Печать  
Автор Тема: QSqlQuery+QThread = bad_alloc  (Прочитано 43581 раз)
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #45 : Май 19, 2014, 12:44 »

Вопрос - как с этим бороться?
Например, использовать преаллокацию или другие структуры хранения данных в памяти.
Или перейти на 64 битные платформы, там такой проблемы не возникнет еще долго. Улыбающийся
« Последнее редактирование: Май 19, 2014, 12:50 от Old » Записан
OKTA
Гость
« Ответ #46 : Май 19, 2014, 12:50 »

Заглянул в исходники QString... Ну да, видимо косяк в непрерывном участке.. Как я понял, QString у меня сжирает 500 метров памяти, дальше пытается сделать realloc, выделив новые 500 метров + еще сколько-то, чего не получается и выкидывает исключение..


Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #47 : Май 19, 2014, 12:51 »

Пробовал Кьют собрать под 64 мингвом - сходу не получилось. Грустный
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
cdsmika
Гость
« Ответ #48 : Май 19, 2014, 14:34 »

Эммм... как умирает?

Быть просто не может смерти при динамическом выделении 500 мб памяти. (если есть хотя бы гиг, а лучше больше памяти в компе)

Разрабатывал одно приложение, оно жрало до 1,8 Гб памяти. Windows XPx32/Windows 7x32/Windows 7x64. Ни разу не было умираний... Мб в креаторе дело?

Мой тест код всего навсего:
Код:
void tst_FtpWorker::initTestCase()
{
    th.setStackSize(1000000000);
    th.start();
    th.wait();
}

Код:
void Thread::run()
{
    QString l;

    while (l.length() < 200000000)
    {
        l.append("1111111111111");
    }
}
Падает (см. приложение)
« Последнее редактирование: Май 19, 2014, 14:57 от cdsmika » Записан
cdsmika
Гость
« Ответ #49 : Май 19, 2014, 14:37 »

А если выполнить в основном потоке
Код:
void tst_FtpWorker::initTestCase()
{
    QString l;

    while (l.length() < 200000000)
    {
        l.append("1111111111111");
    }
}
то все ок (см приложение) и выделенной памяти меньше в два раза
« Последнее редактирование: Май 19, 2014, 14:58 от cdsmika » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #50 : Май 19, 2014, 14:39 »

Пиплы, а при чем тут стек? QString хранит данные в куче. Это же ПИМПЛ.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
OKTA
Гость
« Ответ #51 : Май 19, 2014, 15:49 »

Стэк он случайно прицепился и ни как не отцепляется  Смеющийся
Записан
cdsmika
Гость
« Ответ #52 : Май 19, 2014, 16:03 »

Короче поставил я setStackSize(10000) и заработало также как и в основном потоке, а вот с SQLQuery такое не прокатывает. Теперь падает с bad_alloc и в основном потоке:
Код:
void tst_FtpWorker::initTestCase()
{
    QSqlDatabase udb;
    udb = QSqlDatabase::addDatabase( "QODBC", "conn" );
    udb.setDatabaseName( "Driver={SQL Server Native Client 10.0};Server=(local);Database=ks;UID=sa;PWD=1;" );
    udb.open();

    QStringList l;

    QSqlQuery query( udb );
    query.setForwardOnly(true);
    query.prepare("EXEC dbo.get_initial_data '56FEB471-37A7-494E-AF87-8FC03174C74F'");
    query.exec();

    while (query.next())
    {
        l.append(query.value(1).toString());
    }
}
Повторюсь, что квэрятина возвращает ок 248 метров данных
« Последнее редактирование: Май 19, 2014, 16:11 от cdsmika » Записан
OKTA
Гость
« Ответ #53 : Май 19, 2014, 16:25 »

ради интереса, поставь вместо append что-нибудь типа new char[] с размером того блока, который получаешь из query.
И вопрос по исключениям в тему.. Почему не ловится исключение?? Просто вылетает с сообщением о std::bad_alloc..

Код:
int main(int argc, char *argv[])
{
    while (1) {
        //

        try {
            //

            new char;

        } catch(std::bad_alloc) {
            //

            qDebug() << "BAD ALLOC";
            break;
        }
    }
    return 0;
}
Записан
cdsmika
Гость
« Ответ #54 : Май 19, 2014, 16:46 »

ради интереса, поставь вместо append что-нибудь типа new char[] с размером того блока, который получаешь из query.
И вопрос по исключениям в тему.. Почему не ловится исключение?? Просто вылетает с сообщением о std::bad_alloc..

Код:
int main(int argc, char *argv[])
{
    while (1) {
        //

        try {
            //

            new char;

        } catch(std::bad_alloc) {
            //

            qDebug() << "BAD ALLOC";
            break;
        }
    }
    return 0;
}

Будет все ок. Выяснил. что вылетает именно QSqlQuery::value(int)
Попробую порезать данные на части и работать через файло. Все равно через фтп передавать. Но вот для других задач вопрос что делать. Ведь через файло не везде удобно
« Последнее редактирование: Май 19, 2014, 16:48 от cdsmika » Записан
OKTA
Гость
« Ответ #55 : Май 19, 2014, 16:54 »

а как ты выяснил, что именно на value?
Записан
cdsmika
Гость
« Ответ #56 : Май 19, 2014, 16:56 »

ради интереса, поставь вместо append что-нибудь типа new char[] с размером того блока, который получаешь из query.
И вопрос по исключениям в тему.. Почему не ловится исключение?? Просто вылетает с сообщением о std::bad_alloc..

Код:
int main(int argc, char *argv[])
{
    while (1) {
        //

        try {
            //

            new char;

        } catch(std::bad_alloc) {
            //

            qDebug() << "BAD ALLOC";
            break;
        }
    }
    return 0;
}
Попробовал. Выделяет 1,4 ГБ
Код:
void tst_FtpWorker::initTestCase()
{
    int i = 250000000;
    int j = i;
    while (1)
    {
        try
        {
            new char[j];
            qDebug() << j;
            j = j + i;

        }
        catch(std::bad_alloc)
        {
            qDebug() << "BAD ALLOC";
            break;
        }
    }
}
Записан
OKTA
Гость
« Ответ #57 : Май 19, 2014, 16:59 »

не не не, я имел ввиду другое, ну да ладно, уже поздно  Смеющийся
Записан
cdsmika
Гость
« Ответ #58 : Май 19, 2014, 17:05 »

а как ты выяснил, что именно на value?
А вот
Код:
void tst_FtpWorker::initTestCase()
{
    try
    {
        QSqlDatabase udb;
        udb = QSqlDatabase::addDatabase( "QODBC", "conn" );
        udb.setDatabaseName( "Driver={SQL Server Native Client 10.0};Server=(local);Database=ks;UID=sa;PWD=1;" );
        udb.open();

        QSqlQuery query( udb );
        query.setForwardOnly(true);
        query.prepare("EXEC dbo.get_initial_data '56FEB471-37A7-494E-AF87-8FC03174C74F'");
        query.exec();
        query.first();
        query.value(1);
    }
    catch(std::bad_alloc)
    {
        qDebug() << "BAD ALLOC";
    }
}
bad_alloc на value. Данных в менеджере 248 метров (выделяет 500 метров и падает). Шайтан какой-то
« Последнее редактирование: Май 19, 2014, 17:07 от cdsmika » Записан
OKTA
Гость
« Ответ #59 : Май 19, 2014, 17:21 »

так ты говорил в основном потоке все ок  Непонимающий
Записан
Страниц: 1 2 3 [4] 5 6 7   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 23.