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()?
    
Заранее спасибо за ответы.

  • C++ Утечка памяти, указатели, !*! Hordi, 16:50 , 04-Дек-07 (1)
    • C++ Утечка памяти, указатели, !*! siegerstein, 19:08 , 04-Дек-07 (2)
      >Много текста - мало смысла...

      А какой может быть смысл если это вопросы ... :)

      >
      >В Qt все визуальные элементы, которые принадлежат какому-то родительскому элементу (напр. кнопки
      >на виджете), будут удалены когда вызовется деструктор самого родительского объекта.
      >
      >Т.е. ниже приведенный код корректен:
      >
      >QWidget *p = new QWIdget(0);
      >QLabel *lLabel = new QLabel(p);
      >
      >delete p;

      Я знаю что этот код корректен. Вопрос другой.

      Когда указатели идут через цикл, как потом освободить память.

      if ( int i = 0; i < 25; ++i ) {
         ...
         QLabel *mixDevLabel = new QLabel; // теряем адрес при каждом инкременте
         ...
         }

      Ведь адрес то мы теряем...

      Да и это не один вопрос был...


  • C++ Утечка памяти, указатели, !*! tosha, 20:10 , 04-Дек-07 (3)
  • C++ Утечка памяти, указатели, !*! NuINu, 15:03 , 05-Дек-07 (8)
    • C++ Утечка памяти, указатели, !*! Hordi, 15:47 , 05-Дек-07 (9)
    • C++ Утечка памяти, указатели, !*! siegerstein, 18:15 , 05-Дек-07 (11)
      >>Доброго дня всем!
      >>
      >>И еще несколько вопросов на эту тему.
      >>
      >>1. Кто на практике знает, много ли программ под UNIX имеет утечку
      >>и на сколько она большая?
      >
      >я упал!
      >:-)

      Я думал падают только приложения :))

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

      У меня на копме есть к примеру 1 гиг оперативки.
      Можно просмотреть как-то ее содержимое? Или это невозможно?

      >[оверквотинг удален]
      >
      >   std::cout << "*p = "<< *p << std::endl;
      >   std::cout << "p = " << p  <<
      >std::endl;
      >      //а вот и адресс указателя в
      >памяти, я так понимаю это стек.
      >   std::cout << "&p= " << &p << std::endl;
      >
      >   delete p;
      >}

      Ступил. Перепутал с ссылкой.

      >
      >
      >>Далее...
      >>Вот такой кусок кода приведет к ошибке сегментирования:
      >>
      >>   Qt *p;
      >>   *p = 5;
      >>
      >

      имелось в виду конечно int *p;


      >[оверквотинг удален]
      >>
      >
      >А вот тут вы совершенно правы!
      >
      >
      >>Все нормально. Если я правильно понимаю, new() возвращает адрес в куче (
      >>heap ), и этому указателю вообще не обязательно
      >
      >А вот тут вы ошибаетесь, память выделена под инт, попытаетесь туда что
      >нибудь "побольше" положить и уничтожите другие переменные в куче.

      - вопрос был не об этом
      - разве можно положить в int "побольше"? ИМХО компилятор не даст..

      • C++ Утечка памяти, указатели, !*! vic, 19:56 , 05-Дек-07 (13)
        • C++ Утечка памяти, указатели, !*! siegerstein, 00:37 , 06-Дек-07 (14)
          >[оверквотинг удален]
          >>>>и на сколько она большая?
          >>>
          >>>я упал!
          >>>:-)
          >>
          >>Я думал падают только приложения :))
          >
          >Ок, 8 программ имеют утечку памяти, остальные нет.
          >Ну честно слово, где такую статистику то взять? =)
          >

          Я имею ввиду такое:
          Многие программы имеют утечку, но разработчики это не знают, или знают но не знают как выловть ее ( это очень трудно ), или к примеру opeтoffice дает утечку примерно в 5 Mb или что-то в том роде... То есть тот кто реально знает случаи утечки и насколько они были или есть большие...
          Хочу знать на что мне расчитовать :))

          Не надо утрировать, я понимаю что статистики нигде нету, само собой.

          >[оверквотинг удален]
          >>>простите, доступа к чьей памяти?
          >
          >в линух смотрим в /proc/core =) Это вся память.
          >/proc/<pid>/mem вроде память процесса (не помню точно).
          >Разберетесь - мне расскажите =)
          >
          >>У меня на копме есть к примеру 1 гиг оперативки.
          >>Можно просмотреть как-то ее содержимое? Или это невозможно?
          >
          >Умеем в хексах править программы на лету? =)

          Я разве говорил про править? Я говорил для просмотра... под виндой помню была. Названия не помню.. Давно было.

          >
          >>>>   Qt *p;
          >>>>   *p = 5;
          >>имелось в виду конечно int *p;
          >
          >Все равно нас ждет segfault =) память-то не выделена.
          >Объявлен указатель типа int в никуда.

          Я знаю что будет segfault :))
          Я ж сам про это писал :D
          Имелось ввиду про то что перетупал тип.

          И разве указатель обявлен в никуда?!?


              int *p;
              
              std::cout << *p << std::endl; // значение которое хнатиться по адресу (мусор)
              std::cout << p << std::endl;  // адрес который храниться в указателе (мусор)
              std::cout << &p << std::endl; // адрес самого указателя

          1474660693
          0xb7f43206
          0xbfa98770

          >[оверквотинг удален]
          >>- вопрос был не об этом
          >>- разве можно положить в int "побольше"? ИМХО компилятор не даст..
          >
          >легко, 95% программистов (включая меня =)) это могут. сишные преобразаования типов, всякие
          >memcpy неправильно использованные и т.д. нам помогут.
          >
          >Если серьезно, то возьмите качественные книжки по С и книжки по С++
          >внимательно почитайте. Хотя бы книги господ создателей этих языков (Керниган и
          >Ричи, Страуструп). Вы путаетесь в довольно простых моментах в работе с
          >указателями.

          Возьми,почитай... А я что знания в астрала беру?!? :))




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

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