'QT'에 해당되는 글 2건

  1. 2016.04.19 디버깅 매크로
  2. 2016.03.18 QByteArray 의 reserve() vs resize()

디버깅 매크로

QT 2016. 4. 19. 15:42

[파일 명][함수:라인] 내용


이런 형식이 필요하여 만들었음.


2018.12.27 수정, 이전 버전은 UTF8 지원이 불가함 (한글 출력 안됨)

수정 버전 사용할 것을 추천..


#ifndef DEFINE_MACRO_H

#define DEFINE_MACRO_H


#include <QDebug>


#define ENTIRE_DEBUG_ON     1

#define DEBUG_VERBOSE       1


#if ENTIRE_DEBUG_ON

#if DEBUG_VERBOSE

#define VERBOSE() qDebug("[%s][%s:%d]", __FILE__, __func__, __LINE__)

#endif

#define DEBUG(MESSAGE) qDebug("[%s][%s:%d] %s", __FILE__, __func__, __LINE__, (MESSAGE))

#define SDEBUG(...) { \

    QString arg; \

    arg.sprintf(__VA_ARGS__); \

    qDebug() << QString("[%1][%2:%3]").arg(__FILE__).arg(__func__).arg(__LINE__) << arg.toUtf8(); \

}

#else

#define VERBOSE() ;

#define DEBUG(MESSAGE) ;

#define SDEBUG(...) ;

#endif


#endif // DEFINE_MACRO_H


ex)

VERBOSE(); // 현재 위치 로그 출력

DEBUG("Something is wrong here"); // 현재 위치에 문자열과 함께 로그 출력

SDEBUG("Something is wrong with value [%d]", wrongValue); // 현채 위치에 printf 포맷 형태로 로그 출력


보면 알겠지만 ENTIRE_DEBUG_ON 을 0으로 바꾸면 모든 디버그 메시지 출력을 끈다.

DEBUG_VERBOSE 를 0으로 바꾸면 VERBOSE만 끈다. 이건 응용해서 디버그 레벨을 조절하면 될듯.



Posted by 독뽀
,

SDK Ver. Qt 4.8.6


현상)

QByteArray 객체를 기본 생성자로 선언하고 reserve 로 크기를 정하고 복사를 하니 size가 제대로 나오지 않았다.

resize 로는 정상 동작 하였다.


const char *cba = "great!";

QByteArray ba;
ba.reserve(10);

memset(ba.data(), 0, 10);
mempcpy(ba.data(), (const char*)cba, 6);

qDebug() << "ba = " << ba.data();

qDebug("ba size[%d] ba isNull[%d]", ba.size(), ba.isNull());


원인)

size가 제대로 동작하지 않은 이유..

QByteArray 객체를 기본 생성자로 생성하면 QByteArray 내부 private 변수인 d (구조체 포인터) 값을 shared_null 의 주소 값으로 설정한다. 이후 reserve 를 호출하면 내부적으로 QByteArray의 realloc을 호출하게 되는데 여기서 문제가 발생한다.


realloc 내부를 보면 아래와 같이 x라는 변수에 메모리를 할당 받고 d가 x를 가리키게 한다.


void QByteArray::realloc(int alloc)
{
    if (d->ref != 1 || d->data != d->array) {
        Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc));
        Q_CHECK_PTR(x);
        x->size = qMin(alloc, d->size);
        ::memcpy(x->array, d->data, x->size);
        x->array[x->size] = '\0';
        x->ref = 1;
        x->alloc = alloc;
        x->data = x->array;
        if (!d->ref.deref())
            qFree(d);
        d = x;
    } else {
        Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc));
        Q_CHECK_PTR(x);
        x->alloc = alloc;
        x->data = x->array;
        d = x;
    }

}


d->size 값과 alloc 값 중 작은 값을 size로 넣게 되는데, 이 인자는 reserve 에서 인자로 넘어온 값이 realloc에서도 인자로 넘어가고 메모리를 할당 받게 된다.

하지만 d->size 값이 위의 코드로 인해 d->size 값 (0) 이 다시 기록되고 그 결과 size 함수를 호출하면 0이 나오는 기이한 현상이 발생한다.


이 예로 사용 된 QByteArray 객체는 size() 는 0이지만 data() 메서드로 호출해 보면 값이 들어 있다.



결론)

내가 아직 개념을 잘못 알고 있는 것이 아닐까 생각이 든다.

reserve 는 API 레퍼런스에 나와 있듯이 성능 튜닝 용도로만 사용하거나 사용 안하는 것이 좋겠다.


참고)

reserve는 할당된 크기보다 인자로 넘긴 크기가 클 경우에만 realloc 하는 인라인 함수로 구현. (5.x 에서는 좀 다름)

resize는 현재 크기보다 인자로 넘긴 크기가 클 경우 뿐 아니라 작은 경우에도 realloc을 한다.


'QT' 카테고리의 다른 글

undefined reference to 'vtable for...'  (0) 2016.05.19
반투명 그릴 때 배경 잔상 문제  (0) 2016.05.11
libwinpthread 가 계속 동적 빌드만 될 때  (0) 2016.04.28
디버깅 매크로  (0) 2016.04.19
QT static build with mingw32  (0) 2015.09.17
Posted by 독뽀
,