所以,我可以在Visual Studio中运行这个程序,完全没有问题,产生正确的输出。但是,在Linux终端中编译后,在尝试运行相同的代码时出现了seg错误。在使用GDB进行调试时,给出的信息不是很有用(将在下面提供)。该程序包含两个头文件和三个.cpp文件。我将在下面提供所有这些,以及给出的调试信息。 (如果缩进很奇怪,那是因为提交的4空格代码缩进规则)。我一直试图找到这个问题几个小时无济于事。我觉得这是一个小小的错误。非常感谢你们。
Song.h
#ifndef Song_h
#define Song_h
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <stdlib.h>
using namespace std;
class Song
{
private:
string artist;
string title;
int size;
public:
Song(); //declares blank song array
Song(string _title, string _artist, int _size); //initializes object with given parameters for Song instance
string getArtist() const
{
return artist;
}
string getTitle() const
{
return title;
}
int getSize() const
{
return size;
}
void setArtist(string _artist)
{
artist = _artist;
}
void setTitle(string _title)
{
title = _title;
}
void setSize(int _size)
{
size = _size;
}
bool operator == (Song const &rhs);
bool operator != (Song const &rhs);
bool operator > (Song const &rhs);
bool operator < (Song const &rhs);
};
#endif
TsuPod.h
#ifndef TsuPod_h
#define TsuPod_h
#include "Song.h"
//TsuPod class declaration
class TsuPod
{
private:
struct SongNode
{
Song data;
SongNode *next;
};
SongNode *songs; //the head pointer
static const int MAX_SIZE = 512;
static const int SUCCESS = 0;
static const int FAILURE = 1;
static const int NO_MEMORY = -1;
static const int NOT_FOUND = -2;
int getNumSongs();
int memSize;
public:
TsuPod();
TsuPod(int size);
~TsuPod();
int addSong(Song const &s);
int removeSong(Song const &s);
void shuffle();
void showSongList();
void sortSongList();
int getRemainingMemory();
int getTotalMemory()
{
return memSize;
}
};
Song.cpp
#endif
#include "TsuPod.h"
#include "Song.h"
Song::Song() //default constructor, initializes a blank song
{
artist = "";
title = "";
size = 0;
}
Song::Song(string _artist, string _title, int _size) //constructor for song when arguments are given by user
{
artist = _artist;
title = _title;
size = _size;
}
bool Song::operator == (Song const &rhs) //overloaded for sorting
{
return (title == rhs.title &&
artist == rhs.artist &&
size == rhs.size);
}
bool Song::operator != (Song const &rhs) //overloaded for sorting
{
return (title != rhs.title ||
artist != rhs.artist ||
size != rhs.size);
}
bool Song::operator > (Song const &rhs) //overloaded for sorting
{
if (artist != rhs.artist)
return (artist > rhs.artist);
else
if (title != rhs.title)
return (title > rhs.title);
else
if (size != rhs.size)
return (size > rhs.size);
else
return false;
}
bool Song::operator < (Song const &rhs) //overloaded for sorting
{
if (artist != rhs.artist)
return (artist < rhs.artist);
else
if (title != rhs.title)
return (title < rhs.title);
else
if (size != rhs.size)
return (size < rhs.size);
else
return false;
}
TsuPod.cpp
#include "TsuPod.h"
#include "Song.h"
TsuPod::TsuPod() //default constructor
{
memSize = MAX_SIZE;
}
TsuPod::TsuPod(int _size) //constructor for when user specifies their prefered memory size, prevents input of a size greater than MAX_SIZE or less than 0
{
if (_size > MAX_SIZE || _size <= 0)
memSize = MAX_SIZE;
else
memSize = _size;
}
TsuPod::~TsuPod() //destructor
{
SongNode *p;
while (songs != NULL)
{
p = songs;
songs = songs->next;
delete p;
}
}
int TsuPod::getRemainingMemory() //finds remaining memory, returns int value
{
int memSum = 0;
SongNode *p = songs;
while (p != NULL)
{
memSum += p->data.getSize();
p = p->next;
}
return memSize - memSum;
}
int TsuPod::addSong(Song const &s) //adds song to TsuPod, returns int number to display result, 0 = success, 1 = failure, -1 = not enough memory
{
if (s.getSize() > getRemainingMemory()) //ensures there is enough unsused memory for song
return NO_MEMORY;
if (s.getSize() > 0) //ensures song is valid
{
SongNode *temp = new SongNode;
temp->data = s;
temp->next = songs;
songs = temp;
return SUCCESS;
}
else
return FAILURE;
}
int TsuPod::removeSong(Song const &s) //removes song, returns int value to display result, 0 = success, 1 = failure, -2 = not found
{
if (songs != NULL)
{
SongNode *prev = NULL;
SongNode *p = songs;
if (p->data == s)
{
songs = p->next;
return SUCCESS;
}
while (p != NULL && p->data != s)
{
prev = p;
p = p->next;
if (songs->data == s)
{
songs = p->next;
delete p;
return SUCCESS;
}
else
if (p->data == s)
{
prev->next = p->next;
delete p;
return SUCCESS;
}
else
{
}
}
}
return NOT_FOUND;
}
int TsuPod::getNumSongs() //calculates number of songs, returns int value
{
SongNode *p1 = songs;
int i = 0;
while (p1 != NULL)
{
i++;
p1 = p1->next;
}
return i;
}
void TsuPod::shuffle() //shuffles TsuPod song list, void return value
{
srand((unsigned)time(NULL));
for (int j = 0; j < getNumSongs() * 2; j++)
{
int r1 = rand() % getNumSongs();
int r2 = rand() % getNumSongs();
SongNode *p1 = songs;
SongNode *p2 = songs;
for (int i = 0; i < r1; i++)
p1 = p1->next;
for (int i = 0; i < r2; i++)
p2 = p2->next;
Song temp = p1->data;
p1->data = p2->data;
p2->data = temp;
}
cout << endl << " PLAYLIST SHUFFLED" << endl << endl;
}
void TsuPod::sortSongList() //sorts song list by artist, title, and size respectively, void return value
{
for (SongNode *p1 = songs; p1 != NULL; p1 = p1->next)
{
SongNode *small = p1;
for (SongNode *p2 = p1->next; p2 != NULL; p2 = p2->next)
{
if (small->data > p2->data)
{
small = p2;
}
}
if (p1 != small)
{
Song temp = small->data;
small->data = p1->data;
p1->data = temp;
}
}
cout << endl << " PLAYLIST SORTED" << endl;
}
void TsuPod::showSongList() //shows song list, void return value
{
cout << " ___________________________________________________ " << endl << " TsuPod 2.0" << endl << endl;
cout << " Memory ---- Total: " << getTotalMemory() << " MB" << " -- Remaining: " << getRemainingMemory() << " MB" << endl;
SongNode *p = songs;
int i = 0;
while (p != NULL)
{
i++;
cout << endl << " " << i << ". " << p->data.getArtist();
int artistLength = p->data.getArtist().length();
for (int j = 0; j < (24 - artistLength); j++) //This loop is implemented to evenly space the artist from the song
cout << " ";
cout << p->data.getTitle();
int titleLength = p->data.getTitle().length();
for (int j = 0; j < (24 - titleLength); j++) //This loop is implemented to evenly space the song title from the song size
cout << " ";
cout << p->data.getSize() << " (MB)" << endl;
p = p->next;
}
cout << endl;
}
TsuPod_Driver.cpp
#include <cstdlib>
#include <iostream>
#include "Song.h"
#include "TsuPod.h"
using namespace std;
int main(int argc, char *argv[])
{
TsuPod t;
Song s1("Animals As Leaders", "Another Year", 4);
int result = t.addSong(s1);
cout << " add result = " << result << endl;
Song s2("Gorillaz", "Stylo", 6);
result = t.addSong(s2);
cout << " add result = " << result << endl;
Song s3("August Burns Red", "Meridian", 6);
result = t.addSong(s3);
cout << " add result = " << result << endl;
Song s4("The Ink Spots", "If I Didn't Care", 7);
result = t.addSong(s4);
cout << " add result = " << result << endl;
Song s5("Beatles", "I Feel Fine", 241);
result = t.addSong(s5);
cout << " add result = " << result << endl;
Song s6("Fine Constant", "Sea", 3);
result = t.addSong(s6);
cout << " add result = " << result << endl;
Song s7("Human Abstract", "Nocturne", 9);
result = t.addSong(s7);
cout << " add result = " << result << endl;
Song s8("August Burns Red", "Meridian", 4);
result = t.addSong(s8);
cout << " add result = " << result << endl;
Song s9("Frank Sinatra", "My Way", 5);
result = t.addSong(s9);
cout << " add result = " << result << endl;
t.showSongList();
t.shuffle();
t.showSongList();
t.sortSongList();
t.showSongList();
result = t.removeSong(s1);
cout << " delete result = " << result << endl;
result = t.removeSong(s2);
cout << " delete result = " << result << endl;
result = t.removeSong(s3);
cout << " delete result = " << result << endl;
t.showSongList();
result = t.removeSong(s4);
cout << " delete result = " << result << endl;
result = t.removeSong(s5);
cout << " delete result = " << result << endl;
result = t.removeSong(s6);
cout << " delete result = " << result << endl;
result = t.removeSong(s7);
cout << " delete result = " << result << endl;
result = t.removeSong(s8);
cout << " delete result = " << result << endl;
result = t.removeSong(s9);
cout << " delete result = " << result << endl;
t.showSongList();
cout << " memory = " << t.getRemainingMemory() << endl << endl << endl << endl;
for (int i = 1; i < 33; i++) //tests to ensure that user cannot add a song when there is not enough space available
{
Song s1("August Burns Red", "Meridian", i);
result = t.addSong(s1);
cout << " add result = " << result << endl;
}
t.showSongList();
cin.get();
return EXIT_SUCCESS;
从Linux终端调试信息
Program received signal SIGSEGV, Segmentation fault.
0x0000000000402d50 in Song::getSize() const ()
(gdb) backtrace
#0 0x0000000000402d50 in Song::getSize() const ()
#1 0x00000000004024ac in TsuPod::getRemainingMemory() ()
#2 0x00000000004024fb in TsuPod::addSong(Song const&) ()
#3 0x000000000040112e in main ()
答案 0 :(得分:2)
我没有看到任何TsuPod ::歌曲被初始化的迹象。无法保证在空列表情况下它将为NULL,因此您的
while (p != NULL)
在TsuPod :: getRemainingMemory()中的测试可能会从堆栈传递一个疯狂的值,并在下一行使用p时爆炸。
我推荐
TsuPod::TsuPod():songs(NULL) //default constructor
{
memSize = MAX_SIZE;
}
TsuPod::TsuPod(int _size):songs(NULL) //constructor for when user specifies their prefered memory size, prevents input of a size greater than MAX_SIZE or less than 0
{
if (_size > MAX_SIZE || _size <= 0)
memSize = MAX_SIZE;
else
memSize = _size;
}
确保歌曲以列表结束条件开头。
另外,考虑使用std :: list来代替滚动自己的链表进行列表管理。