Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> null pointer assigment, странный баг 
:(
    Опции темы
H4nter
Дата 12.5.2008, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



При программировании шаблона динамического списка и последующим тестировании возникает такая ошибка в самом конце выполенения программы пишет "null pointer assigment"

Я понимаю, что какой-то указатель ссылается на null и я просто возможно в деструкторе класса списка не удаляю его...
Но отследить, какой, я просто не могу, так как она возникает в самом самом конце выполнения программы, и при завершении она сначала пишет эту строчку, а потом завершает прогу.
Причем заметил, если использовать этот шаблон списка не для хранения объектов, а например примитивного типа int 
Код

List<int>

то такой ошибки не возникает, а если хранить какой-нибудь объект, например точку
Код

List<Point>

то сразу возникает подобная ошибка... кто то возможно сталкивался с подобным?
PM ICQ Jabber   Вверх
Alek86
Дата 12.5.2008, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



это в ветку по C# нужно (или C++ мелкософтский)
здесь же чистый C++

Это сообщение отредактировал(а) Alek86 - 12.5.2008, 16:51


--------------------
user posted image    user posted image
PM MAIL   Вверх
H4nter
Дата 12.5.2008, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



так у меня вопрос по чистому С++ Где ты тут C# видишь?  smile 
мой вопрос как раз таки и подходит под ветку "Общие вопросы по С++"
PM ICQ Jabber   Вверх
Alek86
Дата 12.5.2008, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Код
List<Point>

что-то ни List ни Point в чистых сях не вспоминаются
а угадывать, что за ними скрывается можно долго...

может это все-таки управляемый мелкософтский?


--------------------
user posted image    user posted image
PM MAIL   Вверх
vinter
Дата 12.5.2008, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Alek86, 
Цитата(H4nter @  12.5.2008,  17:48 Найти цитируемый пост)
При программировании шаблона динамического списка




--------------------
Мой блог
PM MAIL WWW   Вверх
Alek86
Дата 12.5.2008, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



аа... тормозю

тогда код в студию, наверное
желательно предельно урезанный


--------------------
user posted image    user posted image
PM MAIL   Вверх
H4nter
Дата 12.5.2008, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



Вот собственно список, выкинул некоторые ненужные методы, дабы урезать код на сколько это возможно
Код

#define CIRCULAR_
#ifndef CNode_
  #include "CNode.H"
#endif
template<class T> class Circular_List {
 private:
  CNode<T> *header;
  CNode<T> *win;
  int _length;
 public :

  Circular_List (void);
  ~Circular_List (void);
  void insert (T &val);
  void insert (void);
  void remove (void);
  void val (T);
  T& val (void);
  CNode<T>* next (void);
  T& gonext (void);
  T& first (void);
  T& last (void);
  int length (void);
  int isFirst (void);
  int isLast (void);
  int isHead(void);
  int isEmpty(void);
  CNode<T>* getcur (void);
  static void SetDebugMode(const unsigned int k);
}; template<class T> unsigned int  Circular_List<T>::debug=0;


template<class T> Circular_List<T>::Circular_List(void) : 
  _length(0)
{
  header = NULL;
  win = header;
  header->setnext(header);
  cout<<"Circular_List was created."<<endl;
  
}

template<class T> Circular_List<T>::~Circular_List (void)
{
  while (length() > 0) {
    last();
    remove ();
  }
 if (debug==0) {
 cout<<"Circular_List was destroyed."<<endl;
 }
}

template<class T> void Circular_List<T>::insert(T &val)
{
  if (header == NULL)
    { header = new CNode<T>(val);
      win = header;
      win->setnext(header); //make circuit
      ++_length;
     // return val;
    return;
    }
  win= win->insert(new CNode<T>(val) );
  
  ++_length;
  //return val;
}

template<class T> void Circular_List<T>::insert(void)
{
  if (header == NULL)
    { header = new CNode<T>();
      win = header;
      win->setnext(header); //make circuit
      ++_length;
     // return val;
    return;
    }
  win= win->insert(new CNode<T>() );

  ++_length;
  //return val;
}

template<class T> void Circular_List<T>::remove (void)
{

  if ( !((win == header)&&(win->next()!=header)) ){ //if header then exit
 // T val = win->val();

  if ( (win == header)&&(win->next()== header) ) // if list include only 1 element
  { //T el = win->val();
    delete header;
    header = NULL;           //make list empty
    win = header;
    header->setnext(header);
    --_length;
    //return el;
  }
else
  if (win->next() == header) // if last element
  {
   CNode<T>* temp=header;
    while(temp->next()!=win)
    { temp=temp->next();
    }
   temp->setnext( win->next() );
   delete win;
   first();
   --_length;
   //return val;
  }
else{
  CNode<T>* temp= header;

  while(temp->next()!=win)// if in the middle of Circular_List
  {
   temp=(CNode<T>*) temp->next();
  }
  temp->setnext( (CNode<T>*)win->next() );
  delete win;
  -- _length ;
  //return val;
    }
  }
//return win->val();
}

template<class T> void Circular_List<T>::val (T v)
{
  if (win!=NULL)
    win->val(v);
}

template<class T> T& Circular_List<T>::val(void)
{
  return win->val();
}

template<class T> CNode<T>* Circular_List<T>::next(void)
{
  return win->next();
}

template<class T> T& Circular_List<T>::gonext(void)
{
  win = (CNode<T>*) win->next();
  return win->val();
}

template<class T> int Circular_List<T>::isEmpty(void)
{
  return ( (header == NULL) && (_length == 0) );
}

template<class T> CNode<T>* Circular_List<T>::getcur(void)
{
  return win;
}



Вот код звена списка:
Код

#define CNode_
template<class T> class CNode {
private:
  T _val;
  CNode *_next;    // связь к последующему узлу
  //enable/disable debug mode
  static unsigned int debug;
public:
  CNode (void);
  CNode (T &el);
  ~CNode (void);
  T&    val(void);
  void val(T el);
  CNode *next(void);
  CNode *insert(CNode<T>*);  // вставить узел после текущего
  void setnext(CNode<T>*);  // установить связь со след. звеном
  static void SetDebugMode(const unsigned int k);
}; template<class T> unsigned int CNode<T>::debug=0;


template<class T> CNode<T>::CNode (void):
_next ( NULL ), _val()
{
 if (debug==0) {
 cout<<"CNode was created."<<endl;
 }
}

template<class T> CNode<T>::CNode (T &el):
_next ( NULL ), _val(el)
{
 if (debug==0) {
 cout<<"CNode was created"<<endl;
 }
}

template<class T> CNode<T>::~CNode (void)
{
 if (debug==0) {
 cout<<"CNode was destroyed."<<endl;
 }
}

template<class T> T& CNode<T>::val(void)
{
 return _val;
}

template<class T> void CNode<T>::val(T el)
{
 _val=el;
}

template<class T> CNode<T>* CNode<T>::next(void)
{
  return _next;
}

template<class T> CNode<T>*  CNode<T>::insert(CNode<T> *b)
{
  CNode *c = _next;
  b->_next = c;
  _next = b;
  return b;
}

template<class T> void  CNode<T>::setnext(CNode<T> *b)
{
_next=b;
}

template<class T> void CNode<T>::SetDebugMode(const unsigned int k)
{
    debug = k;
}


Вот если использовать этот шаблон списка, для объектов, возникает именно то сообщение при завершении...
Думал чтот баг в методе remove, но если закоментировать вызов метода remove в деструкторе, то все равно  smile  

Это сообщение отредактировал(а) H4nter - 12.5.2008, 18:40
PM ICQ Jabber   Вверх
Alek86
Дата 13.5.2008, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



в общем, код не компилится, а без дебага разбирать его нужно долго
так что или постарайся привести в компилируемое состояние (желательно в 1 файле) или сам продебажь (как видно, ты пользовался чем-то типа trace, но этот способ намного хуже дебага, уж поверь)


--------------------
user posted image    user posted image
PM MAIL   Вверх
ksili
Дата 13.5.2008, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Цитата(H4nter @  12.5.2008,  20:48 Найти цитируемый пост)
Я понимаю, что какой-то указатель ссылается на null и я просто возможно в деструкторе класса списка не удаляю его...Но отследить, какой, я просто не могу, так как она возникает в самом самом конце выполнения программы, и при завершении она сначала пишет эту строчку, а потом завершает прогу.

Так создай коротенький список из пары элементов и пройдись пошагово


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
xvr
Дата 13.5.2008, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Судя по "null pointer assigment" у тебя что то вроде BC++ 3.1 Возьми компилятор поновее и под Win32 и прогони свою программу на нем, получишь свой 'null pointer' сразу а не в конце программы  smile По крайней мере можно будет понять где ошибка.

PM MAIL   Вверх
H4nter
Дата 13.5.2008, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



насчет BC++ 3.1 это ты верно подметил, интересно, а почему в новее версии должно быть в начале? smile 


Alek86, ты где компилировал код? Если в BC++ 3.1 то там должно все компилить... В других IDE не пробовал компилить, да мне и не надо.
Ошибка пишется в самом конце, там никакой дебаг не поможет...
PM ICQ Jabber   Вверх
Fazil6
Дата 13.5.2008, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(H4nter @  13.5.2008,  17:49 Найти цитируемый пост)
Ошибка пишется в самом конце, там никакой дебаг не поможет

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

Добавлено через 3 минуты и 31 секунду
Цитата(H4nter @  13.5.2008,  17:49 Найти цитируемый пост)
Alek86, ты где компилировал код? Если в BC++ 3.1 то там должно все компилить...

у тебя функции не все определены. Линковаться это не будет. А на бумажке тебе никто дебажить не будет
PM MAIL   Вверх
xvr
Дата 13.5.2008, 18:15 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(H4nter @ 13.5.2008,  17:49)
насчет BC++ 3.1 это ты верно подметил, интересно, а почему в новее версии должно быть в начале? smile 

Я уже где то освещал этот вопрос. BC 3.1 ДОСосвский компилятор, а под ДОСом никакой защиты памяти нет, т.е. программа может писать что угодно по каким угодно поинтерам (в том числе и нулевым). В startup'е от BC 3.1 применена специальная хитрость - несколько начальных байтов в сегменте данных заполнены специальной сигнатурой, startup по завершению программы проверяет, что сигнатура не изменилась, и если это не так, то делается вывод, что в эту область была запись (и скорее всего по нулевому поинтеру) о чем и выдается сообвествующее предупреждение. В новых компиляторах под Win32 есть аппаратная защита памяти и любая попытка записи по нулевому (или около того) поинтеру приведет к немедленному прерыванию и останову программы, отладчик при этом покажет место, где это произошло.

Добавлено через 10 минут и 50 секунд
Цитата(Fazil6 @ 13.5.2008,  18:00)
Цитата(H4nter @  13.5.2008,  17:49 Найти цитируемый пост)
Ошибка пишется в самом конце, там никакой дебаг не поможет

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

Для ДОСовского компилятора есть разница - это сообщение пишет не дебагер а startup программы  smile Единственный способ поймать эту записть (не считая пошагового прохождения всего и вся с неусыпным контролем всех записей вручную) это воспользоваться hardware breakpoint на запись по заданному адресу. Для этого надо:
  •  Отлаживаться в TD (Turbo Debugger), т.к. BC IDE не поддерживает hardware brealpoint
  •  Найти, куда произошла запись. Например остановиться на процедуре __checknull и посмотреть визуально по ds:0000 где изменены данные
  •  Поставить hardware breakpoint по записи в этот адрес
  •  Перезапустить программу

PM MAIL   Вверх
xvr
Дата 13.5.2008, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Код

template<class T> Circular_List<T>::Circular_List(void) : 
  _length(0)
{
  header = NULL;
  win = header;
  header->setnext(header);
  cout<<"Circular_List was created."<<endl;
  
}
Обрати внимание на строку header->setnext(header);. Угадай, чему равен здесь header?

PM MAIL   Вверх
H4nter
Дата 13.5.2008, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 16.12.2007

Репутация: нет
Всего: нет



xvr, спасибо тебе большое за объяснение!
Счас в качестве типа Т использую не объект а указатель на него, и ошибки такой больше нет.  smile 

Получается, что если в качестве Т подставлять объект (а не указатель на него) то в  присваивании header = NULL; объект Т, содержащийся в header, будет "пытаться" создаться по нулевому адресу...
PM ICQ Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1069 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.