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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ошибка сегментирования, списки, сортировка, .. 
:(
    Опции темы
ihb0
Дата 29.4.2008, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброго времени суток.
С места и в карьер, дам код, целиком, дабы не было потом просьб показать тот или иной кусок:
Код

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define zamena(tmp,a,b) {tmp=a; a=b; b=tmp; }  //макрокоманда обмена значениями

struct Student           //структура для хранения данных студентов 
{
   int tel;
   int kurs;
   char Name[10];
   char Surname[12];
   char gruppa[6];
   int *exams;
};

struct spisok1           //структура для организации двусвязного списка
{
   Student data;        
   spisok1 *next;
   spisok1 *prev;
};


spisok1* start_spisok;    //ведущий элемент списка
Student* Mas;        
spisok1* first  = NULL;
int i, k, Size;
char c;
//------------------------------------------------------------------
void variant()
{
 printf("Тип списка – двусвязный линейный\n");
 printf("Метод сортировки массива – метод Шелла \n");
 printf("Тип поиска – двоичный поиск в массиве\n");
 printf("Тип файла - двоичный\n");
 printf("|=====================================|\n");
}
void AddLink(spisok1* Pred,Student RECdata){    //добавляет новое звено в любом 
    spisok1* Stav=new spisok1;        //месте за ведущим
    Stav->data=RECdata;
    Stav->next=Pred->next;
    Stav->prev=Pred;
    Pred->next=Stav;
    Stav->next->prev=Stav;
    if(start_spisok==NULL) start_spisok=Stav;
}

int Seek(int num)
{ if ( num<1 )  return 1;
    spisok1* orig_cursor = start_spisok;
    start_spisok = first;
    for (int i=0; i<num; i++)
    {
        if (!start_spisok->next)
        {
         start_spisok = orig_cursor;
         return 1;
        }
        start_spisok = start_spisok->next;
    }
    return 0;
}

//---------------------------------------------------------

int GetCurNum()
{ spisok1* orig_cursor = start_spisok;
    start_spisok = first;
    for (i=0; (start_spisok != orig_cursor); i++)
    {start_spisok = start_spisok->next;};
    return i;
}

void Delete()
{
 spisok1* ToDel;

 ToDel = start_spisok;
 if (GetCurNum() != 1)  Seek(GetCurNum()-1);
 else start_spisok= first;
 start_spisok->next = start_spisok->next->next;
 if ((start_spisok == first) && (start_spisok->next)) start_spisok = start_spisok->next;
 delete[] ToDel->data.exams;
 delete ToDel;
}

void DelSP()
{

 spisok1*ToDel = start_spisok;

 if (ToDel->next != ToDel)
 {
    ToDel->prev->next = ToDel->next;
     ToDel->next->prev = ToDel->prev;
     start_spisok = ToDel->prev;
 }
 if (ToDel->next == ToDel) start_spisok = NULL;
    delete[] ToDel->data.exams;
 delete ToDel;
}


void Pokaz(spisok1* Start){
    spisok1* Stav=Start;
if (Stav == NULL)  { printf("список пуст!!!\n");
  getchar(); return;}            
        printf("|==начало списка==|\n");
    for(k=1;Stav!=NULL;k++){    //выводим все поля каждого звена
        printf("\n\t%d-e звено:\n",k);
        printf("Имя: %s\n",Stav->data.Name);
        printf("Фамилия: %s\n",Stav->data.Surname);
        printf("Группа: %s\n",Stav->data.gruppa);
        printf("Телефон : %d\n",Stav->data.tel);
        printf("Курс: %d\n",Stav->data.kurs);
        printf("Результат сессии: ");
        for (int i=1;i<=Stav->data.exams[0];i++)
         {   printf("%d",Stav->data.exams[i]);    }
        Stav = Stav->next;     getchar();
    }
printf("|==конец списка ==|\n");
getchar();
}

void enter(){
  Student *REC = new Student;
  char buf[80];
  int n;
    
    printf("Введите фамилию: \n");
        scanf("%s",buf);
     strcpy(REC->Surname,buf);    //затем в поле структуры
        
    printf("Имя: \n");            
        scanf("%s",buf);
    strcpy(REC->Name,buf);    

    printf("Группа: \n");            
    scanf("%s",buf); 
    strcpy(REC->gruppa,buf);

    printf("Номер телефона: \n");
        scanf("%d",&REC->tel);        

    printf("Курс: \n");
        scanf("%i",&REC->kurs);        

    printf("Введите количество экзаменов: \n");
        scanf("%i",&n);        

    REC->exams = new int[n+1];    
    REC->exams[0] = n;
    printf("Введите результаты экзаменов\n");
    for (i=1;i<=n;i++)
        scanf("%i",&REC->exams[i]);        

    spisok1* End_spisok = start_spisok;
    while(End_spisok->next != NULL)
    {    
    End_spisok = End_spisok->next;//переход на звено
    }
    AddLink(End_spisok , *REC);    //добавляем поля в список
getchar();
}

void copySpAr()  {        //копирует из списка в массив
        
    spisok1*Stav = start_spisok;
    for(Size=0;Stav!=NULL;Size++) Stav = Stav->next;
    Mas = new Student[Size];    //подсчитываем кол-во звеньев
//и инициализируем динам.массив
    Stav = start_spisok;
    for(i=0;i<Size;i++){            
        Mas[i] = Stav->data;    
        Stav = Stav->next;    
    }
}
void copyArSp()  {        //копирует из массива в список
        
    spisok1*Stav = start_spisok;    //инициализируем ведущий элемент
    Stav = start_spisok;
    for(i=0;i<Size;i++){        
        Stav->data = Mas[i];
        Stav = Stav->next;    
    }
    delete(Mas);            
}

void Shell(){            //сортировка методом Шелла
    copySpAr();         
    int j;
    int val;        //интервал  между сравниваемыми элементами
    Student tmp;            
    for (val = Size/2; val > 0; val/=2)     // Выбор интервала  
    for (i = val;i < Size; i++)               
    /* Сравнение пар, отстоящих на val друг от друга */
    for (j = i-val; j >= 0  && Mas[j].tel > Mas[j+val].tel; j -= val)  
    zamena(tmp,Mas[j], Mas[j+val]);        //обмен значениями
    copyArSp();                
}

void save_text(){        //запись в двоичный файл
    FILE* Dv;        
    Dv = fopen("Database.bin","ab");
    spisok1 *Stav = start_spisok;        //инициализируем указатель
    for(Size=0;Stav!=NULL;Size++) Stav = Stav->next;//проход по списку
    Stav = start_spisok;            //чтобы найти размер
    for(i=0;i<Size;i++){            
    fprintf(Dv, "%s %s\n %s %s\n %s %s\n %s %d\n ", "Name:",Stav->data.Name, "Surname:",Stav->data.Surname, "gruppa:",Stav->data.gruppa,"kurs:",Stav->data.kurs);
        Stav = Stav->next;    //переход на следующее
    }
    fclose(Dv);            
}

void read_text(){        //считываем файл
    FILE*Dv;        
    Dv = fopen("Database.bin","rb");
    start_spisok->next =NULL;
    start_spisok->prev =NULL;
    start_spisok = NULL;
    spisok1*Stav = start_spisok;    
    
    for(i=0;i<Size+1;i++){    
    fread(&Stav->data.Name, sizeof(Stav->data.Name),1, Dv);
    fread(&Stav->data.Surname, sizeof(Stav->data.Surname),1, Dv);
    fread(&Stav->data.gruppa, sizeof(Stav->data.gruppa),1, Dv);
        Stav = Stav->next;    
    }
    fclose(Dv);                
}

void Yandex(){                    //двоичный поиск в массиве
   int found  = 0;
copySpAr();            
     int low, high, mid;                    
int key;                    
printf("Введите ключ поиска: \n");
scanf("%i",&key);                
low=0;
high=Size-1;                        
while (low <= high)    {
  mid = ( low + high )/2;             
  if ( key == Mas[mid].tel)        
  {
Seek(mid); 
 found++;
printf("Есть результат! Показать найденное? y/n...\n");

scanf("%s",c);
if (c == 'y') {                        
    printf("Имя: %s\n",Mas[mid].Name);
    printf("Фамилия: %s\n",Mas[mid].Surname);
    printf("Группа: %s\n",Mas[mid].gruppa);
    printf("Курс: %d\n",Mas[mid].kurs);    getchar(); break; }
  return ;
  };
    if (key < Mas[mid].tel)            
      high = mid - 1;                   
    else
       if (key > Mas[mid].tel)            
          low = mid + 1;             
        };
  delete(Mas);                    
}

int main(){

variant();                    
start_spisok -> next= NULL;
start_spisok -> prev = NULL;
start_spisok = NULL;

i=0;
                        
while(i!=10){                    
    printf("\n");
        printf("1 – Создать/дополнить список\n");    
    printf("2 – Сохранить список в файл\n");
    printf("3 – Загрузить список из файла \n");
    printf("4 – Просмотреть список\n");
    printf("5 – Удалить звено\n");
    printf("6 – Сортировка массива \n");
    printf("7 – Поиск в массиве\n");
    printf("10 - выход\n");    
        scanf("%i",&i);    
    switch(i){                        
        case 1:enter();break;    
        case 2:save_text();break;
        case 3:read_text();break;            
        case 4:Pokaz(start_spisok);break;
        case 5:Yandex();    
printf("Вы действительно хотите удалить эту запись? y/n \n");

          scanf("%s",c);    
          if(c=='y')    
           { Delete();    printf("Запись удалена! \n");  break; }
        case 6:Shell();break;                
        case 7:Yandex();break;        
        case 8:DelSP();break;
        }
    }
    return 0;    
}


И так, имеем вот такую портянку.. Предупрежу сразу, код не мой, попросили разобраться с собственно ошибкой(с коей, как выяснилось, сам я справиться не в состоянии). По мере изучения кода расставил кое какие комменты
Суть дела такова: во время выполнения дает ошибку сегментирования, при вызове функции - создание/дополнение списка. На мой взгляд, все выглядит работоспособным, не знаю даже куда и копать. В общем то такова суть вопроса..
PS Код проверен мною на Linux 2.6.17-13mdv #1  2007 x86_64 AMD Athlon™ 64 Processor 3000+ GNU/Linux
Компилятор - g++
PM MAIL   Вверх
MAKCim
Дата 29.4.2008, 20:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(ihb0 @  29.4.2008,  20:43 Найти цитируемый пост)
На мой взгляд, все выглядит работоспособным, не знаю даже куда и копать

отнюдь
подсказка
Цитата(ihb0 @  29.4.2008,  20:43 Найти цитируемый пост)

start_spisok -> next= NULL;
start_spisok -> prev = NULL;


а вообще, программа дырявая
проще заново написать, чем в этой куче г.... искать ошибки (а они будут, поверьте)
но это так, оффтоп

Это сообщение отредактировал(а) MAKCim - 29.4.2008, 20:56


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

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


Новичок



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

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



Цитата(MAKCim @ 29.4.2008,  20:52)
отнюдь
подсказка
Цитата(ihb0 @  29.4.2008,  20:43 Найти цитируемый пост)

start_spisok -> next= NULL;
start_spisok -> prev = NULL;

мм, несомненно, в комментарии бросал это, странно что сюда так выложил. 
Только вот
Код

spisok1* End_spisok = start_spisok;
    while(End_spisok->next != NULL)

не хорошо оно тогда смотрится.

ЗЫ Абсолютно согласен, код весьма "непрост", но одно дело помочь разобраться с ошибкой, а другое писать за людей, не побоюсь этого слова, будущих программистов, это просто неслыханно .)
PM MAIL   Вверх
bsa
Дата 29.4.2008, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(ihb0 @ 29.4.2008,  21:15)
одно дело помочь разобраться с ошибкой, а другое писать за людей, не побоюсь этого слова, будущих программистов, это просто неслыханно .)

Искать ошибки за будущих программистов тоже неслыханно  smile 
PM   Вверх
Бонифаций
Дата 30.4.2008, 03:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Скомпилируйте с ключем -g и без оптимизации.  Запустите. Посмотрите где именно ошибка.

Когда свалится в корку, с помощью gdb загрузите core dump

gdb -c имякорки имяВашегоФайлаСПрограммой

и когда он загрузится, дайте команду bt
и посмотрите стек вызовов и место смерти.



--------------------
 Бонифаций.
 
PM MAIL ICQ Skype GTalk Jabber YIM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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