gpt4 book ai didi

C++ 链表仅在 GNU/Linux 而不是 Windows 中导致段错误

转载 作者:可可西里 更新时间:2023-11-01 14:45:14 26 4
gpt4 key购买 nike

下面是我正在进行的练习中的代码片段。它读取 CSV 并将其输入链表,然后打印到控制台。 CSV 看起来像这样:

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

它在 Linux 和 Windows 中使用 Visual Studio 2010 和 G++ 进行编译。二进制文件在 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;
}

最佳答案

第一次分配 CallList 节点时,将 next 字段设置为 null。

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

您的 printList 遍历列表,直到 workNULLwork 获取其值从未初始化的列表节点的 next 字段。当它结束时,最后一个节点在 next 字段中包含垃圾,您的程序就会终止。

为什么这在 Windows 上是 OK 而不是在 Linux 上是未定义行为的产物,当您尝试访问未初始化的变量时会得到这种结果。

关于C++ 链表仅在 GNU/Linux 而不是 Windows 中导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13042389/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com