我的程序最後出現了分段錯誤問題。除了唯一的錯誤信息,一切都按預期工作。只有當我從我的菜單中選擇第二個選項(參見下面的menu.cpp)時纔會出現這個選項,它需要一個圖類方法(參見Graf.cpp - 「odszukaj_dfs」)。完成所有任務後,退出時出現上述錯誤。這意味着我的錯誤只有在我的會話期間使用此方法時,hoverer會在我通過菜單選項#4安全地退出會話之後發生,無論這兩個調用之間做了什麼(調用哪個菜單選項)。程序結束時出現分段錯誤
我會感謝任何提示什麼是錯的。請讓我知道如果你需要更多的代碼來解決它,我沒有發佈所有這些,以免讓我的帖子太臃腫。其次,原諒在我的代碼中不使用英語 - 該項目是爲我的大學而設,我必須堅持我的母語。先謝謝你。
至於程序本身要做什麼 - 它是從文件讀取圖形並能夠對其執行深度優先搜索。執行後者時會出現問題。
//main.cpp
#include <iostream>
#include "wczytywanie_grafu/wczytaj_nazwe_pliku.h"
#include "wczytywanie_grafu/wczytaj_graf.h"
#include "menu/menu.h"
#include "graf_struktura/Graf.h"
int main(int argc, char *argv[])
{
using namespace std;
const char* npliku = wczytaj_nazwe_pliku(argc, argv);
if(npliku != 0)
{
Graf *g = poprosze_graf(npliku);
while(menu(*g));
delete g;
}
cout << "Do widzenia.\n";
return 0;
}
這裏是出現問題:
//menu.cpp
#include "menu.h"
#include <iostream>
//wyswietla menu dostepnych operacji na poprawnie wczytanym grafie.
bool menu(Graf &g)
{
using namespace std;
int i;
char *token;
cout << endl;
cout << "Jaka operacje wykonac na wczytanym grafie?\n";
cout << endl;
cout << "1) Wyswietlic schemat.\n";
cout << "2) Wyszukac wierzcholek metoda DFS.\n";
cout << "3) Wczytac inny graf.\n";
cout << "4) Opuscic program.\n";
cout << endl;
cout << "Prosze o wybor jednej z powyzszych opcji. ";
while(!(cin >> i) || i < 1 || i > 4)
{
cin.clear();
cin.ignore(1000, '\n');
cout << "\nBlad. Prosze podac desygnujaca odpowiedz liczbe z podanego zakresu. ";
}
cout << endl;
switch(i)
{
case 1 :
g.wyswietl();
break;
case 2 :
cout << "Prosze podac nazwe szukanego wierzcholka. ";
cin >> token;
cout << "Odwiedzone wierzcholki: ";
if(g.odszukaj_dfs(token) == 0)
cout << "\nNie odnaleziono wierzcholka " << token << ".\n";
else
cout << "\nOdnaleziono wierzcholek " << token << ".\n";
break;
// case 3 :
//
// break;
case 4 :
return false;
}
return true;
}
下面是曲線圖定義( 「格拉夫」 是圖形和 「Wierzcholek」 以其節點)
//Graf.cpp
#include "Graf.h"
#include "../lifo/TabDyn.h"
#include "../lifo/Stos.h"
#include <cstring>
/*###########################################################*/
/*####################### WIERZCHOLEK #######################*/
/*###########################################################*/
/*konstruktory*/
Wierzcholek::Wierzcholek(void)
{
sasiedztwo = -1;
nastepny = poprzedni = 0;
sasiedzi = new Wierzcholek* [1*sizeof(Wierzcholek*)];
}
Wierzcholek::Wierzcholek(char* k)
{
klucz = k;
//wierzcholek izolowany grafu.
sasiedztwo = 0;
nastepny = poprzedni = 0;
sasiedzi = new Wierzcholek* [1*sizeof(Wierzcholek*)];
}
Wierzcholek::Wierzcholek(char* k, int s)
{
klucz = k; sasiedztwo = s;
nastepny = poprzedni = 0;
//przygotowanie tablicy sasiadow o stosownym rozmiarze
sasiedzi = new Wierzcholek* [s*sizeof(Wierzcholek*)];
}
Wierzcholek::Wierzcholek(char* k, int s, Wierzcholek** &n)
{
//typowy wierzcholek grafu.
klucz = k; sasiedztwo = s; sasiedzi = n;
nastepny = poprzedni = 0;
}
Wierzcholek::Wierzcholek(char* k, int s, Wierzcholek** &n, Wierzcholek* &nast , Wierzcholek* &poprz)
{
//typowy wierzcholek grafu.
klucz = k; sasiedztwo = s; sasiedzi = n;
nastepny = nast; poprzedni = poprz;
}
/*przeciazenia i metody*/
//relacja rownowaznosci obiektow oparta na identycznosci kluczy
bool Wierzcholek::operator==(Wierzcholek const &prawy) const
{
if (klucz == prawy.klucz)
return true;
else
return false;
}
void Wierzcholek::okresl_ilosc_sasiadow(int n)
{
delete [] sasiedzi;
sasiedzi = new Wierzcholek* [n*sizeof(Wierzcholek)];
sasiedztwo = n;
}
/*###########################################################*/
/*########################### GRAF ##########################*/
/*###########################################################*/
/*konstruktor*/
Graf::Graf(void)
{
pierwszy = ostatni = 0;
rozmiar = 0;
}
/*metody*/
void Graf::dodaj(Wierzcholek* w)
{
if (pierwszy != 0)
{
w->poprzedni = ostatni;
ostatni = w;
ostatni->poprzedni->nastepny = ostatni;
}
else
pierwszy = ostatni = w;
ostatni->pozycja = rozmiar++;
}
void Graf::wyswietl(void)
{
using namespace std;
Wierzcholek *n = pierwszy;
for(int j=0; j < rozmiar; n = n->nastepny)
{
cout << n->klucz << " :";
for(int i=0; i < n->sasiedztwo; i++)
cout << " " << n->sasiedzi[i]->klucz;
cout << " ;\n";
j++;
}
return;
}
int Graf::podaj_rozmiar(void)
{
return rozmiar;
}
Wierzcholek* Graf::odszukaj_dfs(char* &klucz)
{
using namespace std;
//tablica przyporzadkowujaca kazdemu kolejnemu wierzcholkowi grafu
//binarna wartosc oznaczajaca fakt odwiedzenia wierzcholka przez algorytm.
TabDyn<bool> odwiedzony;
for(int i=0; i < rozmiar; i++)
odwiedzony.dodaj(0);
//stos wierzcholkow sasiadujacych z juz odwiedzonymi wierzcholkami.
Stos< Wierzcholek* > stos;
//wierzcholek zdjety ze stosu.
Wierzcholek* biezacy = pierwszy;
//kolejny wierzcholek ciagu wierzcholkow grafu,
//uwzgledniony, aby nie pominac wierzcholkow izolowanych.
Wierzcholek* numerowany = pierwszy;
//zmienna pomocnicza stworzona dla przejrzystosci kodu
//wierzcholek sasiadujacy z biezacym
//dokladany na stos, jezeli nie zostal jeszcze odwiedzony.
Wierzcholek* sasiad = 0;
//elementow grafu jest dokladnie "rozmiar".
for(int i=0; i < rozmiar; i++, numerowany=numerowany->nastepny)
{
cout << "plus: " << numerowany->klucz << endl;
if(odwiedzony[numerowany->pozycja])
continue;
stos.doloz(numerowany);
while(!stos.jest_pusty())
{
biezacy = stos.zdejmij();
if (odwiedzony[biezacy->pozycja])
continue;
else
odwiedzony[biezacy->pozycja] = true;
if(strcmp(biezacy->klucz, klucz) == 0)
{
cout << endl;
return biezacy;
}
//sasiadow jest dokladnie "sasiedztwo".
for(int j=0; j < biezacy->sasiedztwo; j++)
{
sasiad = biezacy->sasiedzi[j];
if(!odwiedzony[sasiad->pozycja])
stos.doloz(sasiad);
}
}
}
cout << endl;
return 0;
}
以下是Stack的文件(這裏是「Stos」)和動態分配表(這裏是「TabDyn」)
#ifndef STOS_H
#define STOS_H
template<typename T> class TabDyn;
template<typename T>
class Stos
{
private:
/*pola*/
TabDyn<T>* pula;
public:
/*konstruktory*/
Stos(void);
Stos(int);
~Stos(void);
/*metody*/
void wyczysc(void);
bool jest_pusty(void) const;
T& top(void);
T zdejmij(void);
void doloz(const T&);
};
#include "Stos.tcc"
#endif
//Stos.tcc
#ifndef STOS_TCC
#define STOS_TCC
#include "TabDyn.h"
template<typename T>
Stos<T>::Stos(void)
{
pula = new TabDyn<T>;
}
template<typename T>
Stos<T>::Stos(int rozmiar)
{
pula = new TabDyn<T>(rozmiar);
}
template<typename T>
Stos<T>::~Stos(void)
{
delete pula;
}
template<typename T>
void Stos<T>::wyczysc(void)
{
pula->wyczysc();
}
template<typename T>
bool Stos<T>::jest_pusty(void) const
{
return pula->jest_pusty();
}
template<typename T>
T& Stos<T>::top(void)
{
return pula->koniec();
}
template<typename T>
T Stos<T>::zdejmij(void)
{
//nalezy uprzednio sprawdzic czy stos nie jest pusty!
T el = pula->koniec();
pula->usun();
return el;
}
template<typename T>
void Stos<T>::doloz(const T& el)
{
pula->dodaj(el);
}
#endif
//TabDyn.h
#ifndef TABDYN_H
#define TABDYN_H
using namespace std;
int const STD_ROZMIAR = 50;
/*###########################################################*/
template<typename T>
class TabDyn
{
private:
/*pola*/
int max_rozmiar;
int akt_rozmiar;
T *przydzial_pamieci;
public:
/*metody*/
TabDyn(int rozmiar = STD_ROZMIAR);
T& operator[](int i);
//usuwa stary przydzial pamieci i nadaje nowy
bool zarezerwuj(int);
//chyba: wyjebac stary przydzial i przydzielic nowy
void wyczysc(void);
//sprawdzic akt_rozmiar
bool jest_pusty(void);
//wskaznik na poczatek plus akt_rozmiar
T& koniec(void);
bool usun(void); //!!! pop_back
// void doloz_nkoniec(const T&); //!!! push_back
void dodaj(const T&); //!!! push_back
};
#include "TabDyn.tcc"
#endif
//TabDyn.tcc
#ifndef TABDYN_TPP
#define TABDYN_TPP
#include <iostream>
/*###########################################################*/
template<typename T>
TabDyn<T>::TabDyn(int rozmiar)
{
przydzial_pamieci = new T [rozmiar*sizeof(T)];
max_rozmiar = rozmiar;
akt_rozmiar = 0;
}
template<typename T>
T& TabDyn<T>::operator[](int i)
{
if(i >= 0 && i < akt_rozmiar)
{
return *(przydzial_pamieci + i);
}
cout << "Blad: Zarzadano wartosci tablicy dynamicznej spoza zakresu. Podano wartosc ostatniego elementu.\n";
return *(przydzial_pamieci + akt_rozmiar);
}
template<typename T>
bool TabDyn<T>::zarezerwuj(int wolumen)
{
if (max_rozmiar == wolumen)
return true;
if (wolumen < akt_rozmiar)
{
cout << "Blad: Nowy zadany rozmiar tablicy dynamicznej nie jest w stanie pomiescic elementow, ktore juz sie w niej znajduja. Odmowa wykonania operacji. " << endl;
return false;
}
T *npamiec = new T [wolumen*sizeof(T)];
if (! jest_pusty())
{
for(int i=0; i < akt_rozmiar; i++)
{
*(npamiec + i) = *(przydzial_pamieci + i);
}
}
max_rozmiar = wolumen;
delete [] przydzial_pamieci;
przydzial_pamieci = npamiec;
return true;
}
template<typename T>
void TabDyn<T>::wyczysc(void)
{
delete [] przydzial_pamieci;
przydzial_pamieci = new T [max_rozmiar*sizeof(T)];
}
template<typename T>
bool TabDyn<T>::jest_pusty(void)
{
return !akt_rozmiar;
}
//zwraca ostatni element tablicy
template<typename T>
T& TabDyn<T>::koniec(void)
{
T& ans = *(przydzial_pamieci + akt_rozmiar - 1);
if(!akt_rozmiar)
std::cout << "Blad, stos jest pusty.\n";
return ans;
}
//usuwa ostatni element tablicy
template<typename T>
bool TabDyn<T>::usun(void)
{
if (akt_rozmiar == 0)
{
std::cout << "Blad: Nie mam co usunac.\n";
return false;
}
akt_rozmiar--;
return true;
}
//dodaje ostatni element tablicy
template<typename T>
void TabDyn<T>::dodaj(const T& el)
{
if (akt_rozmiar + 1 > max_rozmiar)
{
cout << "Uwaga: przekroczono rozmiar tablicy dynamicznej. Zostanie przydzielona nowa wielkosc." << endl;
zarezerwuj(max_rozmiar+1);
}
*(przydzial_pamieci + akt_rozmiar++) = el;
}
#endif
這是我見過的唯一一個谷歌翻譯出現並提供翻譯代碼的問題。 – chris
要求陌生人通過檢查發現代碼中的錯誤並不富有成效。您應該使用調試器或打印語句來識別(或至少隔離)問題,然後回來一個更具體的問題(一旦您將其縮小到10行[測試案例](http:///sscce.org))。 –
@chris:哈哈我正要離開相同的評論。 –