2014-03-14 3 views
0

나는 항상 아래 코드를 사용하여 sqlite 데이터베이스에 연결합니다. 몇 가지 이유로 QSqlDatabase 대신 *QSqlDatabase을 사용하는 방식으로 다시 작성하기로 결정했습니다.QSqlDatabase를 사용할 때 "&"를 사용하면 왜 오류가 발생합니까 (Qt 5.2)?

내가 한 것은 내 이전 코드 (Line_12) 앞에 &을 사용하는 것이 었습니다. 그러나 코드는 줄 6에서 충돌합니다.

어쨌든, 누군가 내게 준 line_14 그리고 그것은 작동합니다.

그래서 ... 이해할 수 없습니다. 첫 번째 코드에 무엇이 잘못되었으며, 왜 제안 된 코드로 이 작동하는지 알 수 없습니다. 라인 12에서

Foo::Foo(QString path_="db_path_name") { 
    InitialDataBase(path_); 
    bool isOpened = db->open(); 
    if(!isOpened) exit(1); 
    else    
     queryExecutor = new QSqlQuery(*db); // --> Line_6 
} 

void Foo::InitialDataBase(QString path_) { 

    // Line_12 => DOESN'T WORK 
    db = &(QSqlDatabase::addDatabase("QSQLITE")); 
    // Line_14 => WORK 
    db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE")); 

    db->setHostName("localhost"); 
    db->setDatabaseName(path_); 
    db->setUserName("admin"); 
    db->setPassword("admin"); 
} 

답변

0

, 당신은 addDatabase()에 의해 반환 된 QSqlDatabase 객체의 주소를 복용하고 있습니다. 이 객체는 일시적이며 명령문이 끝난 직후 파손됩니다 (12 행 이후). 따라서 매달린 포인터, 즉 이미 삭제 된 객체에 대한 포인터로 끝납니다. 매달린 포인터를 역 참조하는 것은 정의되지 않은 동작입니다. 실제로, 그것은 일반적으로 충돌합니다.

줄 14에서 addDatabase()에서 반환 된 임시 QSqlDatabase 개체의 복사본을 만드는 새 QSqlDatabase 개체가 힙에 만들어집니다. 복사 생성자 QSqlDatabase (const QSqlDatabase &)가 여기에 호출됩니다. 임시 오브젝트는 삭제되지만 힙의 사본은 그대로 유지됩니다. 나중에 db을 삭제해야합니다. 그렇지 않으면 메모리 및 리소스 누출로 끝납니다 (DB 연결 열기).

왜 여기에 포인터를 사용합니까? 특히 초보자로서이 예제에서 보여 주듯이 충돌과 누수가 발생합니다.)

관련 문제