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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.03.2011, 19:01   #1
H1ghlander
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 19
По умолчанию указателем на char в структуре

Проблема возникает в функции Show, не могу никак понять как правильно вывести mylist[0].info из структуры LIST, программа компилится нормально, но когда запускается функция Show, программа вылетает с такой ошибкой "Нарушение прав доступа при чтении "0x00000000"."


Код:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

const int M=5;
//Структура области переполнения
struct ITEM {
	int key;
	int release;
	char *info;
	ITEM *next;
};
//Структура основной области
struct LIST {
	int key;
	int release;
	char *info;
	ITEM *headitem;
};

LIST mylist[M];

void Initial()
{
	for (int i=0;i<M;i++)
	{
		mylist[i].key=NULL;
		mylist[i].release=NULL;
		mylist[i].info=NULL;
		mylist[i].headitem=new ITEM;
		mylist[i].headitem->next=NULL;
	}
}

int Hash(int key)
{
	return key % 10;
}

ITEM *GetItem(int index, int &count)
{
	ITEM *CurrentItem=mylist[index].headitem;
	cout << mylist[index].headitem;
	while(CurrentItem->next!=NULL){
			CurrentItem=CurrentItem->next;
			++count;
	}
	return CurrentItem;
}


int Add(int key, int release, char *str)
{
	int count=0;
	int hash=Hash(key);
	if (++count && mylist[hash].key==NULL){   //Если нет такого ключа
		//++count;
		mylist[hash].key=key;
		mylist[hash].release=release;
		mylist[hash].info = new char [strlen(str)+1];
		strcpy (*mylist[hash].info, str);
					}
	else		//Если есть
	{
		cout << endl << "Возникла конфликтная ситуация" << endl;
		ITEM *CurrentItem=GetItem(hash,count);
		ITEM *tmp=new ITEM;
		tmp->key=key;
		tmp->release=release;
		tmp->info = new char [strlen(str)+1];
		strcpy (tmp->info, str);
		tmp->next=NULL;
		CurrentItem->next=tmp;
		CurrentItem=tmp;
	}
	return count;
}


int Search(int key, int &count)
{
	int flag=0;
	int hash=Hash(key);
	if (++count && mylist[hash].key==key)
		flag=1;
	else
	{
		ITEM *tmp=mylist[hash].headitem->next;
		while(++count && tmp!=NULL)
		{
			if (tmp->key==key)
			{
				flag=1;
				break;
			}
			tmp=tmp->next;
		}
	}
	if (flag) 
		return 1;
	else 
		return 0;
}



void Show()
{
	cout << endl;
	for (int i=0; i<M; i++)
	{
		cout << "Table["<< i << "] = " << mylist[i].key << "|" << mylist[i].release << "|" << mylist[0].info << " : ";
		ITEM *tmp=mylist[i].headitem->next; //Указатель на следующий список
		while(tmp!=NULL)
		{
			cout << tmp->key << "|" << tmp->release << "|" << tmp->info <<" ";
			tmp=tmp->next; 
		}
		cout << endl;
	}
}

int Del(int key)
{
	int flag=0;
	int hash=Hash(key);
	if (mylist[hash].key==key)
	{
		if (mylist[hash].headitem->next==NULL)
		{
			flag=1;
			mylist[hash].key=NULL;
		}
		else
		{
			mylist[hash].key=mylist[hash].headitem->next->key;
			ITEM *tmp=mylist[hash].headitem->next;
			mylist[hash].headitem->next=tmp->next;
			flag=1;
			delete tmp;
		}
	}
	else
	{
		ITEM *prev=mylist[hash].headitem;
		ITEM *tmp=mylist[hash].headitem->next;
		while(tmp!=NULL)
		{
			if (tmp->key==key)
			{
				prev->next=tmp->next;
				delete tmp;
				flag=1;
				break;
			}
			else
			{
				prev=tmp;
				tmp=tmp->next;
			}
		}
	}
	return flag;
}

int main()
{
	setlocale(LC_ALL,"Russian");
	int key, release;
	char str[50];
	Initial();
	int count;
	char action;
	do
	{
		cout	<< "1. Добавить" << endl
			<< "2. Искать" << endl
			<< "3. Показать" << endl 
			<< "4. Удалить" << endl
			<< "0. Выход" << endl
			<< " = ";
		cin >> action;
		switch(action)
		{
		case '1':
			cout << endl << "Введите ключ = ";
			cin >> key;
			cout << endl << "Введите релиз = ";
			cin >> release;
			cout << endl << "Введите информацию = ";
			cin >> str;
			count=0;
			if (Search(key, count)!=0)
				cout << endl << "Ключ был использован, сравнений = " << count << endl;
			else
			{
				count = Add(key, release, str);
				cout << endl << "Ключ добавлен. Cравнений = " << count << endl;
			}
			break;
		case '2':
			cout << endl << "Введите ключ = ";
			cin >> key;
			count=0;
			if (Search(key, count)!=0)
				cout << endl << "Найдено, сравнений = " << count << endl;
			else
				cout << endl << "Не найдено" << endl;
			break;
		case '3':
			Show();
			break;
		case '4':
			cout << endl << "Введите ключ = ";
			cin >> key;
			if (Del(key)==1)
				cout << endl << "Удалено" << endl;
			else
				cout << endl << "Не найдено" << endl;
			break;
		case '0':
			break;
		default:
			cout << endl << "Ошибка" << endl;
			break;
		}

	}while(action!='0');
	cin.get();

}

Последний раз редактировалось H1ghlander; 27.03.2011 в 10:26.
H1ghlander вне форума Ответить с цитированием
Старый 26.03.2011, 21:30   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Не надо ее обходить, ее надо исправлять. Ошибка явно говорит, что вы пытается читать по указателю, который не проинициализирован. Т.е. объявили, а память не выделили.
p51x вне форума Ответить с цитированием
Старый 26.03.2011, 21:52   #3
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Там в функции Add в случае добавления нового элемента в список (в случае конфликтной ситуации всё нормально как раз), заполнение поля info закомментировано, т.е. оно не инициализируется.
pu4koff вне форума Ответить с цитированием
Старый 26.03.2011, 23:55   #4
H1ghlander
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 19
По умолчанию

Что? Никто не знает как эту проблему можно обойти?
H1ghlander вне форума Ответить с цитированием
Старый 27.03.2011, 10:25   #5
H1ghlander
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 19
По умолчанию

Не, не это я для теста там закоментировал, с разкоментированными тоже самое.
Цитата:
Не надо ее обходить, ее надо исправлять. Ошибка явно говорит, что вы пытается читать по указателю, который не проинициализирован. Т.е. объявили, а память не выделили.
А почему тогда, если я вывожу в самой функции add mylist[hash].info, то все путем, а если в функции show, то ошибка.
H1ghlander вне форума Ответить с цитированием
Старый 27.03.2011, 10:38   #6
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

В Адд вы выводите то, что заполняли. В Шоу попадаете до заполнения, не все номера заполненые, ...
p51x вне форума Ответить с цитированием
Старый 27.03.2011, 11:00   #7
H1ghlander
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 19
По умолчанию

Не понял, как это туда попадает до заполнения. Почему тогда c другими элементами структуры (release, key) все ок.
H1ghlander вне форума Ответить с цитированием
Старый 27.03.2011, 15:00   #8
H1ghlander
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 19
По умолчанию

Ну помогите разобраться, я действительно не понимаю в чем дело. Если char info использовать без указателя, то все отличено работает, но мне нужно именно с указателем и получается такая фигня.
H1ghlander вне форума Ответить с цитированием
Старый 27.03.2011, 16:07   #9
WebbMan
Форумчанин
 
Регистрация: 16.01.2011
Сообщений: 168
По умолчанию

Цитата:
struct ITEM {
int key;
int release;
char *info;
ITEM *next;
};
//Структура основной области
struct LIST {
int key;
int release;
char *info;
ITEM *headitem;
};
Попробуйте изменить в одной из структур *info на чё нибудь другое например на *info_1
WebbMan вне форума Ответить с цитированием
Старый 27.03.2011, 16:18   #10
H1ghlander
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 19
По умолчанию

Цитата:
Сообщение от WebbMan Посмотреть сообщение
Попробуйте изменить в одной из структур *info на чё нибудь другое например на *info_1
Не понятно, чем это может помочь?
Но в любом случае я проверил - не помогло.
H1ghlander вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
преобразование типов char-const char student101 Помощь студентам 8 01.12.2010 20:45
Массив с указателем Seferus Общие вопросы C/C++ 2 13.11.2010 17:57
Ошибка cannot convert from 'char *' to 'char [100]' Stellvertreter Общие вопросы C/C++ 5 30.05.2010 00:02
Ошибка с указателем nusik Общие вопросы C/C++ 3 15.07.2009 14:14
Есть таблица - В ней три поля int, char, char нужно чтобы данные заносились в таблицу Mysql Muahahaha PHP 8 27.03.2008 11:17