The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"C++ Утечка памяти, указатели"
Отправлено siegerstein, 04-Дек-07 15:57 
Доброго дня всем!

Есть вопрос по поводу утечки памяти ( memory leak ) в C++.
Я пишу приложение под Qt, и на сколько я знаю Qt сам как бы
освобождает все указатели и все такое. Я не очень в кое-чем уверен, поэтому у меня  куча вопросов:

Пишу в топик по C++, так как по большей части здесь будет именно про C++...

   if ( int i = 0; i < 25; ++i ) {
   ...
   QLabel *mixDevLabel = new QLabel;
   ...
   }

Если посмотреть на этот код, то видно что утечка есть, так как адрес на который указывал mixDevLabel
каждый раз перезаписывается ( если я правильно понимаю ).
Не понимаю как Qt сам умудряется освободить память ?!

Я вижу только такое решение как освободить потом всю память:


   // .hpp
   ...
   QSlider **slider;
   ...

   // .cpp
   MainWindow::MainWindow (  ) {
   ...
   slider = new QSlider * [ 25 ];
   ...
   if ( int i = 0; i < 25; ++i ) {
   ...
    slider [ i ] = new QSlider [ 1 ] ;
   ...
   }
   ...
   };

   MainWindow::~MainWindow (  ) {
     for ( int i = 0; i < 25; i++ ) {
         delete [  ] slider [ i ];
   }
     delete [  ] slider;
   }

То есть для этого надо знать  что потом освобождать, а для этого как минимум надо
сделать каждый объект разным ( при помощи двухмерного массива, к примеру ).
И теперь мы можем обратится к объекту как к slider [ i ].
И освобождать память так же - через [ i ].

А как можно освободить память в случае Qt, если один и то же объект инициализируется разным адресом каждый раз?


Вот как проверить что Qt действительно освобождает память?

Пробовал valgrind, ИМХО  он не совсем корректно показывает утечку ( часто показывает в нормальных приложениях утечку, то
ли это родная утечка Qt, че-ли? ).

Я подумал так: если узнать адреса на которые он указывал, а потом проверить свободные они или нет.
Это можно как то организовать?

   if ( int i = 0; i < 25; ++i ) {
   ...
   std::cout << mixDevLabel << std::endl;
   QLabel *mixDevLabel = new QLabel;
   ...
}

Это выведет на экран адреса на которые указывал указатель, но как проверить действительно ли они освободились?

И еще несколько вопросов на эту тему.

1. Кто на практике знает, много ли программ под UNIX имеет утечку и на сколько она большая?
2. Есть ли программа для просмотра ( доступа ) памяти под UNIX? ( Помню под винду была написана на Delphi )
3. Средства для контроля утечки

Указатели:

Как я понимаю нету способов узнать адрес самого указателя?

   int *p;
Тут мы создаем указатель но тип int.

Если я правильно понимаю, он сейчас может указывать на что-угодно, и содержать тоже какое-угодно значение.
Но тогда непонятно вот что: если запустить к примеру вот такой кусок кода:

   #include <iostream>

   int main() {
    
    int *p;
    
    std::cout << *p << std::endl;
    std::cout << p << std::endl;

   }

то каждый раз он покажет разный адрес - но одинаковое значение.
Как это может быть? Если каждый раз меняется адрес на который он указывает, то соответственно доложено меняется значение.

Далее...
Вот такой кусок кода приведет к ошибке сегментирования:

   Qt *p;
   *p = 5;
    
Так как мы пытаемся записать число 5 в не положенную нам область памяти ( если я правильно понимаю )
    
но,
    
   int *p = new int;
   *p = 5;
    
Все нормально. Если я правильно понимаю, new() возвращает адрес в куче ( heap ), и этому указателю вообще не обязательно
теперь на что-то указывать чтобы записать туда свое значение, так как роль адреса переменной теперь играет адрес возращенный new()?
    
Заранее спасибо за ответы.

 

Ваше сообщение
Имя*:
EMail:
Для отправки новых сообщений в текущей нити на email укажите знак ! перед адресом, например, [email protected] (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.

На сайте действует частичное премодерирование - после публикации некоторые сообщения от анонимов могут автоматически скрываться ботом. После проверки модератором ошибочно скрытые сообщения раскрываются. Для ускорения раскрытия можно воспользоваться ссылкой "Сообщить модератору", указав в качестве причины обращения "скрыто по ошибке".



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру