C ++ переполнение с новой отладкой ключевых слов - PullRequest
0 голосов
/ 23 июня 2009

У меня сложная проблема с отладкой, возможно, из-за недостатка понимания того, как c ++ управляет памятью. Код слишком длинный для публикации, но основные настройки таковы:

global_var = 0;
int main() {
  for(i = 0; i < N; ++i) {
    ClassA a;
    new ClassB(a); // seems to be problem!
  }
}

Для некоторых N, global_var повреждается (больше не равно 0). В конструкторах ClassA или ClassB нет ничего, что связывалось бы с global_var.

Замена new ClassB(a) на ClassB b(a), кажется, решает проблему, хотя это не позволяет мне делать то, что я хочу (создать boost::ptr_vector с экземплярами new ClassB(a)).

Есть идеи, что может пойти не так?

Обновление: Я действительно делаю что-то вроде:

global_var = 0;
int main() {
  boost::ptr_vector<ClassB> myobjects;
  for(i = 0; i < N; ++i) {
    ClassA a;
    myobjects.push_back(new ClassB(a)); // seems to be problem!
  }
}

Оба создают проблемы. Но почему это проблема? Должен ли я делать что-то еще, чтобы поместить кучу объектов в очередь? Я использую myobjects как основу для шаблона команд.

Обновление

`classB 'выглядит так:

class ClassB {
public:
  ClassB() {}
  ClassB(ClassA a) : a_(a) {}
private:
  ClassA a_;
}

ClassA - это простая инициализация списка (в реальной жизни).

Проблема?

Обновление Я полагаю, что это может быть связано с тем, что global_var на самом деле является сложным матричным типом, и могут быть проблемы с тем, как он выделяет память.

Ответы [ 6 ]

2 голосов
/ 23 июня 2009

Память в C ++ не освобождается автоматически по умолчанию. Результат

  new ClassB(a); // seems to be problem!

создается в куче. Адрес памяти никому не назначен. Поэтому нельзя вручную удалить его как

  ClassB* b = new ClassB(a); // creates a B, returns an address,
                             // and stores the address in b.
  delete b;       // deletes memory at address "b"

Ошибка удаления памяти может привести к переполнению кучи в других областях памяти вашей программы, что приведет к перезаписи вашей глобальной переменной. Это может произойти без присвоения результата new переменной, если она не удалена.

1 голос
/ 23 июня 2009

Есть ли в classA конструктор копирования? Если да, то как это выглядит? Если нет, создайте конструктор копирования в classA и посмотрите, решит ли это проблему.

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

0 голосов
/ 24 июня 2009

После долгих исследований это поведение оказалось из-за ошибки в базовом классе global_var. В способе глобального и статического выделения памяти была небольшая ошибка.

0 голосов
/ 23 июня 2009

Вы можете установить точку останова записи данных на global_var, чтобы узнать, где она записывается.

В отладчике MSVC установите точку останова в строке 'for'. Когда он туда попадет, выберите «New Breakpoint-> New Data Breakpoint ...» в меню «Debug» и введите & global_var. Продолжить. Отладчик сломается при следующей записи переменной.

GDB может сделать это тоже, но я забыл синтаксис.

0 голосов
/ 23 июня 2009

Я подозреваю что-то в конструкторе копирования класса А.

0 голосов
/ 23 июня 2009

Скорее всего, это ошибка в одном из двух конструкторов (ClassA или ClassB), которая перезаписывает память global_var или повреждает какую-то другую память, что в итоге приводит к ее перезаписи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...