2016-10-25 2 views
0

다음 메서드는 런타임 중에 첫 번째 줄에 이중 자유 또는 손상 (빠른) 오류를 생성합니다. 이는 프로그램이 실행되는 동안 1 초 또는 35 초에 무작위로 발생합니다.이중 자유 또는 손상 (빠른) 오류를 알아낼 수 없습니다.

QSharedPointer<QPixmap> Utils::loadImg(QString fileName) 
{ 
    QPixmap *pixmap = new QPixmap(fileName); 
    QSharedPointer<QPixmap> qspPixmap(pixmap); 
    return qspPixmap; 
} 

이것은 정적 인 방법으로, 실제로는 Qt가 제공하는 스마트 포인터를 사용하여 픽스맵을 얻습니다. 일단 스마트 포인터를 얻으면 나중에 사용하기 위해 맵 구조에 저장합니다. 맵 구조에서 항목을 제거하면 메모리를 확보해야하며 그렇게하는 것처럼 보입니다. loadImg (QString) 메서드는 자체 스레드에서 실행중인 다른 메서드 (Qt에서 제공 한 QtConcurrent 및 QFuture 사용)에 의해 호출된다는 점에 유의하십시오.

정말 문제가 무엇인지 알 수 없습니다. 디버거는 첫 번째 줄을 문제가있는 줄로 표시합니다.

미리 도움을 주셔서 감사합니다.

+1

"첫 번째"줄은 정확히 무엇입니까? Linux를 사용하고 있다면 valgrind를 사용해보십시오. –

+3

그 라인에 도달하기 전에 뭔가 나쁜 일이 일어 났을 가능성이 있지만 메모리 관리자가 손상을 발견 한 것입니다. 거꾸로 작업하고 그 시점까지 모든 메모리 관리를 점검해야합니다. – molbdnilo

+1

valgrind에서 앱을 실행하면 처음에 힙이 손상된 곳을 추적하는 데 도움이 될 수 있습니다. –

답변

1

pixmaps가 암시 적으로 공유되므로이 방법은 의미가 없습니다. 가치로 전달하십시오! 메서드 내에서 문자열 인수를 수정하지 않는 한 const 인수로 문자열 인수를 전달해야합니다.

당신은 완전히 자유롭게 QMap<QString, QPixmap>을 가질 수 있으며 모든 것을 값으로 취급합니다.

메인 스레드가 아닌 모든 스레드에서이 메서드를 호출하면 정의되지 않은 동작이 호출됩니다. 대신 QImage을 사용해야합니다.

으로 보여야 방법은 다음과 같습니다 당신이 임의의 스레드에서 호출하려는 경우

QPixmap Utils::loadImg(const QString & fileName) 
{ 
    Q_ASSERT(QThread::currentThread() == qApp->thread()); 
    return QPixmap{fileName}; 
} 

, 당신이해야합니다 어느 경우에

QImage Utils::loadImg(const QString & fileName) 
{ 
    return QImage{fileName}; 
} 

물론이 방법은 사소한 것이므로 올바른 스레드에서 픽스맵을 작성하는지 확인하는 것 이외에는 사용할 필요가 없습니다.

+0

도와 주셔서 감사합니다. 당신의 대답이 내 문제를 해결했습니다. QPixmap과 QImage가 암묵적으로 공유된다고 말한 이유 때문에 QSharedPointer를 사용하면 안되는 이유를 이해합니다. 그러나 주 스레드에서 메서드를 호출 할 때 QPixmap을 반환 할 수있는 동안 주 스레드에서 호출하지 않는 대신 QImage를 반환해야하는 이유를 이해할 수 없습니다. 그걸 설명해 주시겠습니까? 고맙습니다. – Soc

+1

'QPixmap'은 메인 쓰레드 외부에서는 사용할 수 없습니다. 그게 다야. 'QPixmap'을 전혀 사용할 필요가 없습니다. 기본 그래픽 백엔드는 래스터 백엔드이고 모든 픽스맵은 내부적으로 화면 호환 형식의 QImages입니다. 그래서 당신은'QImage'를 사용하여 시작할 수도 있습니다. 래스터 백엔드에서'QPixmap'을 위해 ** 모든 종류의 속도 이점이 없습니다 **. 없음. 네이티브 코드와 상호 작용할 때만 사용할 필요가 있습니다. –

관련 문제