const T & QVector::at ( int i ) const
?
Да, уважаемый именно так. Мало того, компилятор не то что ошибку, но даже ворнига не пишет. И это работает.
Меня тоже это потрясло. Искать утечки памяти в языке и библиотеке, с которыми НЕ знаком. Вообще.
Вас это будет потрясать до тех пор, пока Вы не осознаете разницу между указателем на константу и константным указателем.
Перед тем, как отвечать на этот пост, пожалуйста покурите внимательно этот код
class A
{
public:
void NonConstMethod() {}
};
void main()
{
QVector<A*> vectorA;
A* a = new A;
vectorA.append( a );
vectorA.at( 0 )->NonConstMethod();
delete a;
}
Возможно, вы будете вновь потрясены, но компилятор примет данный код как вполне себе кошерный и ни в одном месте не выругается.
Далее, предлагаю покурить следующий фрагмент
class A
{
public:
void NonConstMethod() {}
};
void main()
{
const A* a1 = (const A*)0x123123;
a1 = (const A*) 0x111222;
// a1->NonConstMethod();
A* const a2 = (A*) 0x222333;
// a2 = (A*) 0x444555;
a2->NonConstMethod();
}
Если Вы раскоментируете закоментированные строки - компилятор выдаст ошибку. Не поленитесь, вставьте этот код в IDE, скомпилируйте и запустите, возможно так Вы лучше проникнитесь сутью вопроса.
Также рекомендую вдумчиво почитать
http://www.cap-design.ru/ccc/5.htm и обратить внимание на разделы "Указатель на константу" и "Константный указатель". Буду рад, если мои выкладки Вам будут полезны.
Далее, прошу не обсуждать этот момент в данном топике, поскольку он его прямо не касается. Если Вам интерестно это обсудить и найти истину, можете создать отдельный топик и там это обсуждать. Я с удовольствием присоединюсь к обсуждению.
Увожу далее разговор от QVector-a. Здесь много было скзано про методы QVector::reserve() и QVector::resize().
Ок, я их добавлял для того чтобы память под элементы выделялась только один раз (да, resize для этого не подходит и там возникает проблема, которую все озвучили несколько раз. внимательный читатель заметил, что я сразу же поправился и стал использовать метод reserve, который соответствует поставленной задаче).
Все. Отказываемся от их использования. Нету их.
void JustDoIt()
{
int objectsAmount = 300;
QVector<QObject*>* objectsVector = new QVector<QObject*>;
for ( int i = 0; i < objectsAmount; i++ )
{
QObject* object = new QObject;
objectsVector->append( object );
qDebug( "objectsVector->size() = %d", objectsVector->size() );
}
for ( int i = 0; i < objectsAmount; i++ )
{
delete objectsVector->at( i );
}
delete objectsVector;
}
int main(int argc, char *argv[])
{
__LEAKS_CHECK_START;
JustDoIt();
__LEAKS_CHECK_END;
return 0;
}
Компилируем, запускаем и имеем снова ту же проблему "258 memory leaks detected".
Подчёркиваю, нарицаний на QVector у меня нет и использую я его исключительно ради удобства демонстрации проблемы. Я не думаю, что память течёт в векторе - мне не всё ясно с очищением памяти из-под QObject-a.
Увожу разговор от QVector-a совсем
void JustDoIt()
{
QObject* obj1 = new QObject;
QObject* obj2 = new QObject;
QObject* obj3 = new QObject;
QObject* obj4 = new QObject;
delete obj1;
delete obj2;
delete obj3;
delete obj4;
}
На выходе имеем "8 memory leaks detected". Т.е. проблема, как мне кажется, где-то с QObject-ом. Или это не проблема, а корректное поведение? Ткните меня носом в мануал, где это написано, а то я что-то не могу понять что происходит.
Напомню, что проверки делаю под Symbian эмулятор и девайс. Просто потому, что знаю как делать замеры выделенной памяти, чтобы искать утечки (методика отработана не на одном проекте и до последнего времени себя оправдывала). Если кто-то знает, как это программно делать на линуксе и на винде (а лучше всего вообще средствами самой Qt) скажите пожалуйста, буду благодарен.