Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: проблема в программе  (Прочитано 8839 раз)
0 Пользователей и 1 Гость смотрят эту тему.
mihansk
Гость
« : 23-11-2009 13:06 » 

Это класс книга.

Код:
#include "kniga.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>

kniga::kniga(void)//конструктор по умолчанию
{nomer=0;
 fio=NULL;
 nazvanie=NULL;
 year=0;
 kolvo=0;
 NEXT=NULL;
}

kniga::~kniga(void)//деструктор
{
}
kniga::kniga(int nomer1, char* fio1, char *nazvanie1, int year1, int kolvo1)//конструктор с параметрами
{nomer=nomer1;
 int k;
 k=strlen(fio1);
 fio=new char[k];
 strcpy(fio,fio1);
 int t;
 t=strlen(nazvanie1);
 nazvanie=new char[t];
 strcpy(nazvanie,nazvanie1);
 year=year1;
 kolvo=kolvo1;


}
kniga::kniga(kniga&K1)//конструктор копирования
{nomer=K1.nomer;
 int k;
 k=strlen(K1.fio);
 fio=new char[k];
 strcpy(fio,K1.fio);
 int t;
 t=strlen(K1.nazvanie);
 nazvanie=new char[t];
 strcpy(nazvanie,K1.nazvanie);
 year=K1.year;
 kolvo=K1.kolvo;


}
void kniga::setnomer(int nomer1)
{nomer=nomer1;}
void kniga::setfio(char *fio1)
{
int k;
 k=strlen(fio1);
 fio=new char[k];
 strcpy(fio,fio1);


}
void kniga::setnazvanie(char *nazvanie1)
{int t;
 t=strlen(nazvanie1);
 nazvanie=new char[t];
 strcpy(nazvanie,nazvanie1);
}
void kniga::setyear(int year1)
{
year=year1;
}
void kniga::setkolvo(int kolvo1)
{kolvo=kolvo1;

}
void kniga::setall(int nomer1, char *fio1, char *nazvanie1, int year1, int kolvo1)
{nomer=nomer1;
 int k;
 k=strlen(fio1);
 fio=new char[k];
 strcpy(fio,fio1);
 int t;
 t=strlen(nazvanie1);
 nazvanie=new char[t];
 strcpy(nazvanie,nazvanie1);
 year=year1;
 kolvo=kolvo1;


}

int kniga::getnomer(void)
{return nomer;
}
char* kniga::getfio(void)
{return fio;}
char* kniga::getnazvanie(void)
{return nazvanie;}
int kniga::getyear(void)
{return year;}
int kniga::getkolvo(void)
{return kolvo;}

void kniga::input(void)
{printf("vvedite nomer\n");
scanf("%i",&nomer);
printf("vvedite fio\n");
char fio1[100];
scanf("%s",fio1);
int k;
 k=strlen(fio1);
 fio=new char[k];
 strcpy(fio,fio1);
printf("vvedite nazvanie\n");
char nazvanie1[100];
scanf("%s",nazvanie1);
int t;
t=strlen(nazvanie1);
nazvanie=new char[t];
 strcpy(nazvanie,nazvanie1);
 printf("vvedite god vbIpuska\n");
 scanf("%i",&year);
 printf("vvedite kolvo ekzemplarof\n");
 scanf("%i",&kolvo);
}

void kniga::print(void)
{printf(" %i ",nomer);
printf(" %s " ,fio);
printf("%s",nazvanie);
printf(" %i ",year);
printf(" %i \n",kolvo);

}

void kniga::setNEXT(kniga* NEXT1)

{NEXT=NEXT1;}


kniga* kniga::getNEXT(void)
{return NEXT;

}


Это класс списка, наследуемый от класса книга.

Код:


#include "knigalist.h"
#include "kniga.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>

knigalist::knigalist(void)
{n=0;
START=NULL;

}

knigalist::~knigalist(void)
{
}
knigalist::knigalist(int n1)
{kniga* tmp;
 kniga* cur;
 n=n1;
 int i;
 for(i=0;i<n;i++)
{
tmp= new kniga;
tmp->input();

if(i==0)
{START=tmp;
START->setNEXT(NULL);}
  else
{tmp->setNEXT(START);
START=tmp;}


}

}
void knigalist::printlist(void)
 { kniga* cur;
 for(cur=START;cur!=NULL;cur=cur->getNEXT())
 { cur->print();}

 
 }
void knigalist::addSTART(kniga* p)
{if(START==NULL)
{START=p;}
else {p->setNEXT(START);
START=p;}





}

void knigalist::addEND(kniga* p)
{kniga* cur;
for (cur=START;cur->getNEXT()!=NULL;cur=cur->getNEXT());
if(START==NULL)
{START=p;}
else
{
          cur->setNEXT(p);
  p->setNEXT(NULL);
}


}

kniga* knigalist::delEND(void)
{
kniga *cur, * tmp;
for(cur=START;cur->getNEXT()->getNEXT()!=NULL;cur=cur->getNEXT());
if(START!=NULL)


{tmp=cur->getNEXT();
cur->setNEXT(NULL);
return tmp; }


}

kniga* knigalist::vzat(int t)
{kniga* cur;
int k;

for (cur=START;cur!=NULL;cur=cur->getNEXT())
{if(cur->getnomer()==t)
{


k=cur->getkolvo();
if(k==0)
{printf("knigi net\n");}
else
{k--;
printf("kniga vzata\n");
cur->setkolvo(k);

return cur;}

}

}
}

kniga* knigalist::otdat(int t)
{kniga* cur;
int k;

for (cur=START;cur!=NULL;cur=cur->getNEXT())
{if(cur->getnomer()==t)
{
k=cur->getkolvo();

k++;
printf("kniga otdana\n");
cur->setkolvo(k);

return cur;

}
}
}


Это сама программа.

Код:

#include "kniga.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "kniga.h"
#include "knigalist.h"
void main(void)
{kniga BB(7,"hhh","nnn",1991,1);
kniga BV(5,"hhh","nnn",1991,1);
knigalist A;
A.addSTART(&BB);
A.addEND(&BV);




A.printlist();
A.vzat(7);
A.printlist();

getch();

}



Компилятор ошибки не выдает, но при запуске выдает ошибку :Unhandled exception at 0x004120a6 in kursovaia.exe: 0xC0000005: Access violation reading location 0xcccccce0.
и указывает на
Код:
kniga* kniga::getNEXT(void)
{return NEXT;

}

помогите найти ошибку
« Последнее редактирование: 23-11-2009 13:53 от Джон » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 23-11-2009 13:09 » 

У тебя же уже была тема насчёт этого списка...
Ну да ладно. Вот смотри:
Код:

void knigalist::addEND(kniga* p)
{kniga* cur;
for (cur=START;cur->getNEXT()!=NULL;cur=cur->getNEXT());
   if(START==NULL)
   {START=p;}
   else

   {cur->setNEXT(p);
   p->setNEXT(NULL);
   }
}
и
Код:
kniga* knigalist::delEND(void)
{kniga *cur, * tmp;
for(cur=START;cur->getNEXT()->getNEXT()!=NULL;cur=cur->getNEXT());
   if(START!=NULL)
   {tmp=cur->getNEXT();
   cur->setNEXT(NULL);
   return tmp; }
}
(cur->getNEXT() и cur->getNEXT()->getNEXT() соответственно) - я уже придумывал тебе случай, когда такое будет приводить к падению программы. Как минимум, ошибка в этом коде.

p.s. обрамляй код тегами [code][/code] и форматируй его чуть-чуть аккуратнее - глаза можно сломать, пока читаешь.
« Последнее редактирование: 23-11-2009 13:11 от Вад » Записан
mihansk
Гость
« Ответ #2 : 23-11-2009 14:22 » 

ну там случаи были для печати списка. а тут мне дойти до предпоследнего элемента в addEND и до препредпоследнего в delEND.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-11-2009 14:49 » 

А какая разница? Проблема-то всё та же: пусть у тебя есть пустой список, и ты хочешь дойти до "предпоследнего элемента в addEND". И нет у тебя ни последнего, ни предпоследнего, поэтому метод getNEXT ты вызываешь не для объекта, а для какого-то мусора в памяти.
Записан
mihansk
Гость
« Ответ #4 : 24-11-2009 09:05 » 

if(START==NULL) так у меня же есть проверка на пустой список
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-11-2009 09:12 » 

Правильно, есть. Но она совершенно бессмысленна, поскольку выполняется после цикла, в котором происходит описанный сбой.
То есть, проверка, конечно, нужна, но она к этой ошибке не имеет отношения, поскольку выполняется в совсем других целях и уже после отыскания "предпоследнего элемента"

Протрассируй код пошагово в отладчике - и сам всё увидишь.
« Последнее редактирование: 24-11-2009 09:14 от Вад » Записан
mihansk
Гость
« Ответ #6 : 24-11-2009 10:25 » 

Код:
kniga* knigalist::addEND(void)
{kniga *cur, * tmp;
cur=START;
if(START==NULL)
{START=p;}
else
{for(cur=START;cur->getNEXT()->getNEXT()!=NULL;cur=cur->getNEXT());
{cur->setNEXT(p);
   p->setNEXT(NULL);
   }

}
так?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 24-11-2009 10:46 » 

По-моему, не так. Второе добавление в список не падает?
Записан
mihansk
Гость
« Ответ #8 : 25-11-2009 09:08 » 

падает
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 25-11-2009 10:05 » 

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

Вот смотри: тебе нужно добавить элемент в конец списка, для чего последнему элементу нужно установить указатель на новый элемент. Для этого нужно отыскать нужный элемент.
И у тебя есть два случая: первый - когда список пустой, и добавлять элемент пока некуда; второй - когда в списке есть элементы.
В первом случае ты уже делаешь всё правильно - просто устанавливаешь START (надеюсь, NEXT у него проинициализирован NULL-ом?)
Во втором случае, тебе нужно найти последний элемент. То есть, тот, у которого getNEXT() равен NULL (при чём тут getNEXT()->getNEXT(), который у тебя?).
Вот ты и пишешь:
Код:
if (START == NULL){
    START = p;
}
else {
    for (cur = START; cur->getNEXT() != NULL; cur = cur->getNEXT());
    cur->setNEXT(p);
}
если список не пустой, то cur=START будет нормальным элементом, и мы можем проверить, есть ли у него следующий. Если следующего нет - цикл завершится и мы добавим свой элемент сюда. Если есть - перейдёт к следующему элементу и опять проверит, есть ли следующий. И так далее. Если в уме такие проверки сложновато делать - можешь написать на бумажке порядок выполнения программы пошагово. Или хотя бы пройти в отладчике и поглядеть, как она исполняется. Угадывать ответы не надо - надо понимать Улыбаюсь
« Последнее редактирование: 25-11-2009 10:09 от Вад » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines