分段故障(核心转储) - 代码在VS中工作但在Linux终端中不起作用

时间:2015-04-22 21:16:26

标签: c++ linux windows segmentation-fault sigsegv

所以,我可以在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 ()

1 个答案:

答案 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来代替滚动自己的链表进行列表管理。