Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.10.2011, 12:03   #1
litviak
Пользователь
 
Регистрация: 02.04.2011
Сообщений: 19
По умолчанию С++ Линейные списки. Ошибка сегментации при добавлении элемента.

Компилирую на gcc. При добавлении первого же элемента выдает ошибку.
Код:
#include <iostream>
#include <stdlib.h>
using namespace std;
template <class Type> class List{
	class Node{
		public:
		Type d;
		Node *next;
		Node(Type dat=0){
			d=dat;
			next=0;
		};
	};
	Node *pbeg;
	public:
		List(){
			pbeg=0;
		};
		~List(){
			if(pbeg!=0){
				Node *pv=pbeg;
				while(pv){
					pv=pv->next;
					delete pbeg;
					pbeg=pv;
				};
			};
		};
		void add(Type d){
			Node *pv=new Node(d);
			Node *pb=pbeg;
			while(pb->next!=0)
				pb=pb->next;
			pb->next=pv;
		};
		Node *find(Type key){
			Node*pv=pbeg;
			while((pv->d!=key)&&pv)
				pv=pv->next;
			return pv;
		};
		bool remove(Type key){
			Node*pv=find(key);
			if(pv){
			if(pbeg->d==key){
				pbeg=pbeg->next;
				return 1;
			};
			Node *prev;
			while((prev->next->d!=key)&&(prev->next)){
				prev=prev->next;
			};
			prev->next=pv->next;
			delete pv;
			return 1;
			};
			return 0;
		};
		void print(){
			Node *pv=pbeg;
			while(pv){
				cout<<pv->d;
				pv=pv->next;
			};
		};
	};
int main(){
	List <int> a;
	cout<<"Введите кол-во элементов";
	int n;
	cin>>n;
	int key;
	cout<<"Вводите элементы";
	for(int i=0;i<n;i++){
		cin>>key;
		a.add(key);
	};
	cout<<"введите ключ для поиска :";
	cin>>key;
	if(a.find(key)!=0)
		cout<<"элэмент найден";
	else cout<<"ненайден";
}
litviak вне форума Ответить с цитированием
Старый 28.10.2011, 12:13   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Отладчик же. Прекрасно бы увидели, на какой строке падает.
Код:
void add(Type d){
            Node *pv=new Node(d);
            Node *pb=pbeg;//Чему у нас равен pbeg в начале?
            while(pb->next!=0)//Где программа попытается найти значение next?
                pb=pb->next;
            pb->next=pv;
        };
Abstraction вне форума Ответить с цитированием
Старый 28.10.2011, 12:18   #3
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

И не удивительно, что ошибка !
Код:
		List(){
			pbeg=0;
		};
...
			Node *pb=pbeg;
			while(pb->next!=0)
Вы пытаетесь обратиться по нулевому адресу !

А надо так:
Код:
void add(Type d){
	if ( !pbeg) pbeg = new Node(d); // Если первый элемент
	else
	{
		Node *pb = pbeg;
		while(pb->next)
			pb = pb->next;
		pb->next = new Node(d);
	}
};
An1ka вне форума Ответить с цитированием
Старый 28.10.2011, 12:19   #4
litviak
Пользователь
 
Регистрация: 02.04.2011
Сообщений: 19
По умолчанию

Отладчика нет.Да и пользоватся не умею.
Переписал конструктор спасибо.
Код:
List(){
			pbeg->next=0;
		};
Теперь список заполняет но с поиском беда:
*** glibc detected *** ./a.out: free(): invalid pointer: 0xbff4b87c ***
элэмент найденАварийный останов

У меня же указатель на список создается сразу
Код:
Node *pbeg;
Хотя только что увидел что
Код:
элэмент найден
. Но ошибка все равно меня смушает
Но это видимо изза отсутсвия return в майне.
Нет не изза этого...
При поиске элемента которого нет Ошибку сегментации опять выдает.

Последний раз редактировалось Stilet; 29.10.2011 в 19:58.
litviak вне форума Ответить с цитированием
Старый 28.10.2011, 12:30   #5
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Сообщение от litviak Посмотреть сообщение
Отладчика нет.Да и пользоватся не умею.


Теперь список заполняет но с поиском беда:
*** glibc detected *** ./a.out: free(): invalid pointer: 0xbff4b87c ***
элэмент найденАварийный останов
То есть как так нет? Это в чём вы работаете? Пишем код в блокноте, компилируем из консоли? "Немедленно брось бяку!"

Судя по сообщению, кто-то пытается вызвать delete для указателя, не указывающего на занятую, динамически выделенную с помощью new память. Ну, и этот код
Код:
while((pv->d!=key)&&pv)
просто умоляет упасть при очередном обращении по нулевому адресу.

P.S. Ага, как вижу, он именно что и падает.
Abstraction вне форума Ответить с цитированием
Старый 29.10.2011, 16:38   #6
litviak
Пользователь
 
Регистрация: 02.04.2011
Сообщений: 19
По умолчанию

Цитата:
Сообщение от litviak Посмотреть сообщение
Компилирую на gcc
Реально пишу в текстовом редакторе и компилирую gcc через терминал

Как лучше этот while сделать тогда?

Это из-за услвовия (pv->d!=key) то что он обращается к несуществующему указателю?

Последний раз редактировалось litviak; 29.10.2011 в 16:42.
litviak вне форума Ответить с цитированием
Старый 29.10.2011, 16:46   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ОФФТОП:
Цитата:
Реально пишу в текстовом редакторе и компилирую gcc через терминал
да верим мы верим, я аналогично пишу часто(правда через Edit Pad Pro)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 29.10.2011, 16:54   #8
litviak
Пользователь
 
Регистрация: 02.04.2011
Сообщений: 19
По умолчанию

Код:
		Node *find(Type key){
			Node*pv=pbeg;
			while(pv)
				if(pv->d==key)return pv;
				pv=pv->next;
			return pv;
		};
Переписал ф-цию вот так. Только дома стоит винда с Visual Studio. С которой не могу разобраться...Выдает тоже непонятнейшие ошибки:

Цитата:
Ошибка 1 error LNK2001: неразрешенный внешний символ "_mainCRTStartup" c:\visual studio 2010\Projects\Списки шаблон\Списки шаблон\LINK Списки шаблон


Ошибка 2 error LNK1120: 1 неразрешенных внешних элементов c:\visual studio 2010\Projects\Списки шаблон\Debug\Списки шаблон.exe 1 1 Списки шаблон
С этим разобрался. Не привязал cpp к проэкту.
Переписал констуруктор вот так:
Код:
List(){
			pbeg=new Node;
		};
Уходит в бесконечный цыкл на ф-ции поиска. Не работает:
Код:
pv=pv->next;

Последний раз редактировалось litviak; 29.10.2011 в 18:30.
litviak вне форума Ответить с цитированием
Старый 29.10.2011, 18:34   #9
litviak
Пользователь
 
Регистрация: 02.04.2011
Сообщений: 19
По умолчанию

Я дурак, сам все понял. Забыл включить скобки в
Код:
while(pv)
				if(pv->d==key)return pv;
				pv=pv->next;
litviak вне форума Ответить с цитированием
Старый 30.10.2011, 08:16   #10
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от litviak Посмотреть сообщение
Переписал констуруктор вот так:
Код:
List(){
			pbeg=new Node;
		};
Зачем создавать какой-то элемент в пустом списке ? Обнулять pbeg в пустом списке как раз правильно, а при добавлении элементов проверять пустой ли список или нет.
Добавление элемента в этом случае уже написано в третьем посте: http://programmersforum.ru/showpost....11&postcount=3
An1ka вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при добавлении данных Ehha1234 БД в Delphi 0 19.06.2010 20:33
Ошибка при добавлении в базу Ele БД в Delphi 4 20.04.2010 13:22
Ошибка при добавлении запроса KARUSHEV Помощь студентам 3 27.01.2010 08:45
Ошибка сегментации при вызове system("PAUSE") Lavisa Общие вопросы C/C++ 9 01.08.2009 18:14
Ошибка сегментации при вызове system("PAUSE") Lavisa Помощь студентам 0 29.07.2009 17:43