Связанный список C ++, вызывающий ошибку сегментации только в GNU / Linux, а не в Windows

Ниже приведен фрагмент кода из упражнения, над которым я работаю. Он читает CSV и вводит его в связанный список, а затем печатает на консоль. CSV выглядит так:

5,3,19
7,12,2
13,15,25
22,0,7

Он компилируется с использованием Visual Studio 2010 и G ++ как в Linux, так и в Windows. Двоичный файл выполняется в командной строке Windows XP, но возникает ошибка сегментации при запуске в Git Bash (Windows XP) и под Linux. Используя отладчик (под Linux) я изолировал проблему printList() не распознает конец связанного списка.

Почему это происходит и что я могу сделать, чтобы предотвратить это? Любые предложения будут ценны.

#include <cstdlib>
#include <sstream>
#include <iostream>
#include <fstream>

using namespace std;

// CSV source file parameters
const char *cSourceCSV = "source.csv";
const int iFieldsPerRow = 3;

enum direction_t {UP=1, STATIONARY=0, DOWN=-1};

// struct to hold data in a singly linked list
struct CallList {
float fTime; // time of call in seconds from beginning
int iFromPos;
int iToPos;
direction_t d_tDirectionWanted();
CallList *next;
};

direction_t CallList::d_tDirectionWanted() {
int iBalance = iFromPos - iToPos;
direction_t d_tDirection;
if (iBalance < 0) d_tDirection = DOWN;
else if (iBalance == 0) d_tDirection = STATIONARY;
else if (iBalance > 0) d_tDirection = UP;
return d_tDirection;
}

CallList *head;
CallList *temp;
CallList *work;

void populateList(const char *cSourceCSV) {
string sRow;
string sValue;
ifstream ioSource (cSourceCSV); // the source file placed in an input stream
if (ioSource.is_open()) { // making sure the stream/file is open
while (ioSource.good()) { // repeat while stream is still healthy
// obtain the data
temp = new CallList;
getline (ioSource,sRow); // reading each row of data
stringstream s_sRow(sRow); // now entering the row into a stringstream
for (int i=0; i<iFieldsPerRow; i++) {
ws(s_sRow); // if there is whitespace in s_sRow remove it <-this is
// stopping the program from crashing but I get an extra line 1,1,1
getline (s_sRow,sValue,','); // now getting the data from the
// stringstream using the comma as a delimiter
if (i==0) {
temp->fTime = stof(sValue);
}
else if (i==1) {
temp->iFromPos = stoi(sValue);
}
else if (i==2) {
temp->iToPos = stoi(sValue);
}
}
// the stationary calls are excluded
if (temp->d_tDirectionWanted() == STATIONARY) continue;

// place the remaining data in the linked list
if (head == NULL) {
// insert the head
head = temp;
}
else {
//********* THIS WORKS *************
work = head;
// nothing fancy needed here as list is already in time order
while(work != NULL) {
if (work->next == NULL) {
work->next = temp;
break;
}
work = work->next;
}
}
//************************************
}
ioSource.close();
}
else cout << "Error opening file: " << cSourceCSV << endl;
return;
}

//********* BUT THIS DOESN'T, WHY? *************
void printList(){
work = head;
while (work != NULL) {
printf("Time: %*.1f, From: %*i, To: %*i, Dir: %*i\n", 5, work->fTime, 2, work->iFromPos, 2, work->iToPos, 2, work->d_tDirectionWanted());
if (work->next == NULL) break;
else work = work->next;
}
return;
}
//************************************int main(int argc, char *argv[]) {
populateList(cSourceCSV);
printList();
return 0;
}

3

Решение

Когда вы выделяете свой узел CallList в первый раз, установите next поле в ноль.

temp = new CallList;
temp->next = NULL;

Ваш printList пересекает список до work является NULL но work получает свою ценность от next поле вашего списка узлов, которые никогда не инициализируются. Когда он доходит до конца, последний узел содержит мусор в next поле и ваша программа умирает.

Почему это нормально в Windows, а не в Linux — это артефакт Неопределенного поведения, который вы получаете, когда пытаетесь получить доступ к неинициализированной переменной.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]