Списки

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

Необходимо так: 1-ая запись - имя студента, 2-ая - его оценка.
Что у меня не так??

Код: Выделить всё

struct list
{
	char c[20];
	char x[10];
	list *next;
}*p,*top,*prev,*cur;

void show();
void push(); // for fio;
void push2(); // for marks

char n;

int main()
{
	top=NULL;
	char key,value;
	int done=false;
	while(!done)
	{
		system("cls");
		show();
		printf("\nA)dd\nQ)uit\n");
		key=getchar();
		switch(toupper(key))
		{
		case 'A':
			push();
			push2();
			break;
		case 'Q':
			done=true;
			break;
		}
	}
	return 0;
}
void push()
{
	printf("\n Input:\n");
	p=new list;
	scanf("%s",&p->c);
	p->next=NULL;
	while(cur && p->c > cur->c)
	{
		prev=cur;
		cur=cur->next;
	}
	if(prev==NULL)
	{
		p->next=top;
		top=p;
	}
	else
	{
		p->next=cur;
		prev->next=p;
	}
}
void push2()
{
	printf("\n input marks:\n");
	printf("\n how mach?:\n");
	scanf("%i",&n);
	
	for(;n;n--)
	{
		p=new list;
	scanf("%s",&p->x);
p->next=NULL;
	while(cur && p->x > cur->x)
	{
		prev=cur;
		cur=cur->next;
	}
	if(prev==NULL)
	{
		p->next=top;
		top=p;
	}
	else
	{
		p->next=cur;
		prev->next=p;
	}
	}
}
void show()
{
	p=top;
	if(p==NULL)
		printf("\n list is empty\n");
	else
		printf("\n LIST:\n");
	while(p)
	{
		printf("%s   %s\n",p->c,p->x);
		p=p->next;
	}
}
ydantezs
Сообщения: 6
Зарегистрирован: 25 май 2010, 13:59

в структуре list разве оценка типа char?? попробуй float, int.
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

т.е. это не важно что там 2ое . Пускай там будет еще одна надпись типа строки. ( например 1-ое имя и 2-ое фамилия)
Albor
Сообщения: 491
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

смотри ф-цию push(): при каждом вызове, указателю р присваивается новый адрес. То есть каждую новую запись ты пытаешся записать в новый список, при этом к старому ты доступа уже не имеешь - это есть утечка памяти. Зачем на эту функцию возлагать лишний функционал (запрос ввода и ввод информации)? Она (судя по названию) должна только добавлять данные в список. При объявлении указателей инициализируй их значением NULL, тогда будешь знать, есть уже объект или нет, например

Код: Выделить всё

list * pList(NULL);
//...
if(pList==NULL) // есть ли список? 
{// списка ещё нет (указатель ещё не получил значение)
   pList=new list;// создадим его
}
if(pList)// на всякий случай проверим, а то вдруг система не выделила память под список
    pList->push();// выполнится только, если список существует
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

А каким образом сохраняется доступ к старому?
Albor
Сообщения: 491
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

Евгений Александрович писал(а):А каким образом сохраняется доступ к старому?
Если нужно хранить указатели на выделенную память, то нужно создать контейнер (массив, например)

Код: Выделить всё

List * pList [10];
for(int i=0;i<10;i++)
  pList[i]=new List;
Так ты получишь 10 списков и вся выделенная память будет под контролем. Если же делать, как сделано у тебя, то указатель р при первом обращении к new получит какое-то значение1, а при следующем - значение2, то есть значение1, если его не присвоить другой переменной или где-то не сохранить в другом месте, будет потеряно и к этому участку памяти доступа уже не будет, то что там находится нельзя будет использовать. Почитай внимательно про new и delete в литературе. Данные операторы используются в паре, если ты обратился к new и выделил память, то обязательно нужно и обращаться к delete для её освобождения. Иначе, при интенсивном выделении памяти ты получишь краш, так как память не бесконечна.
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

большое спасибо
Ответить