c++ - 链表 - EXC_BAD_ACCESS。我认为该错误是因为我错误地删除了一个节点,但我将不胜感激任何建议

标签 c++ list exc-bad-access

void LinkedList::insertBack(int stationID, int year, int month, double temp) {
Node* newNode = new Node(stationID, year, month, temp);
if (tail != nullptr)
    tail->next = newNode; //ERROR - EXC_BAD_ACCESS code = 2
tail = newNode;
if (head == nullptr) { 
    head = newNode; 
}
}

这是我的一个项目代码的一部分,它接收数据并将它们放入链表中。我在错误中写了它出现在哪一行。我不认为实际问题出在这个函数中,但我会非常感谢任何帮助。谢谢你!我在下面附上了我的 .cpp 文件的其余部分。我也附上了我的 main.cpp。

LinkedList::LinkedList(string name) :
head(nullptr), tail(nullptr), name(name) {}

// Destructor
LinkedList::~LinkedList() {
clear();
cout << "LinkedList destructor called" << endl;
}

//Default constructor
LinkedList::LinkedList(){
    cout << "LinkedList constructor called." << endl;
    dataObj = new int;
    *dataObj = 0;
    return;
}

//Copy Constructor
LinkedList::LinkedList(const LinkedList& origClass) {
     cout << "Copy Constructor called." << endl;
    dataObj = new int;
    *dataObj = *(origClass.dataObj);
    return;
}

 //Copy Assignment Operator
LinkedList& LinkedList::operator=(const LinkedList& objToCopy){
     cout << "Assignment op called." << endl;

    if (this != &objToCopy) {
        delete dataObj;
        dataObj = new int;
        *dataObj = *(objToCopy.dataObj);
    }
     return *this;
 }

void LinkedList::empty() {
    if (head)
        delete head;
}

void LinkedList::setName(string name) {
this->name = name;
}

string LinkedList::getName() const{
    return name;
}

void LinkedList::insertFront(int stationID, int year, int month, double temp) {
    Node* newNode = new Node(stationID, year, month, temp);
    newNode->next = head; // attach to list
    head = newNode;
    if (tail == nullptr) { // empty list
    tail = newNode; // only node is both head and tail
}
 }

void LinkedList::insertBack(int stationID, int year, int month, double temp) {
    Node* newNode = new Node(stationID, year, month, temp);
    if (tail != nullptr)
        tail->next = newNode; // attach to list
    tail = newNode;
    if (head == nullptr) { // empty list
        head = newNode; // only node is both head and tail
    }
}


void LinkedList::insertBack(int stationID, string command, int firstYear, int      lastYear) {

    Node* newNode = new Node(stationID, command, firstYear, lastYear);
    if (tail != nullptr)
        tail->next = newNode; // attach to list
    tail = newNode;
    if (head == nullptr) { // empty list
    head = newNode; // only node is both head and tail
    }
}



void LinkedList::clear() {
    Node* del = head;
    while (del != NULL) {
        head = head->next;
        delete del;
        del = head;
     }
     head = tail = NULL;
 }

int LinkedList::size()
{
    int cnt = 0;
     Node* node = head;
    while (node != NULL) {
        cnt++;
        node = node->next;
    }
    return cnt;
}

void LinkedList::print() const {
    print(cout);
}

void LinkedList::print(ostream& os) const {
    os << this;
}

//Temp List
double LinkedList::getStationID(int index) const {
     Node* current= head;
    double count = 0.0;
     double ID = 0.0;
    while (current != NULL) {
        if (count == index) {
            ID = current->stationID;
        }
        count++;
        current = current->next;
    }
    return ID;
}

double LinkedList::getYear(int index) const {
    Node* current= head;
    double count = 0.0;
    double year = 0.0;
     while (current != NULL) {
        if (count == index) {
             year = current->year;
        }
        count++;
        current = current->next;
    }
    return year;
}
double LinkedList::getMonth(int index) const {
    Node* current= head;
    double count = 0.0;
    double month = 0.0;
    while (current != NULL) {
        if (count == index) {
            month = current->month;
        }
        count++;
        current = current->next;
      }
    return month;
 }
double LinkedList::getTemp(int index) const {
    Node* current= head;
    double count = 0.0;
    double temp = 0.0;
     while (current != NULL) {
        if (count == index) {
            temp = current->temperature;
        }
        count++;
        current = current->next;
    }
    return temp;
 }

 //Query List
 string LinkedList::getCommand(int index) {
    Node* current= head;
    double count = 0.0;
    string phrase = "";
    while (current != NULL) {
        if (count == index) {
            phrase = current->command;
        }
        count++;
        current = current->next;
    }
    return phrase;
}
double LinkedList::getFirstYear(int index) const {
    Node* current= head;
    double count = 0.0;
    double first = 0.0;
    while (current != NULL) {
        if (count == index) {
            first = current->firstYear;
        }
         count++;
         current = current->next;
     }
     return first;
}
double LinkedList::getSecondYear(int index) const {
    Node* current= head;
    double count = 0.0;
    double last = 0.0;
    while (current != NULL) {
        if (count == index) {
            last = current->lastYear;
        }
        count++;
        current = current->next;
    }
    return last;
}


Node* LinkedList::search(double val)
{
    Node* node = head;

    /* traverse the list */
    while (node != NULL) {
        /* Target! */
        if(node->value == val)
        {
            return node;
        }
        /* move to the next one */
        node = node->next;
    }
    return NULL;
}

ostream& operator<<(ostream& os, const LinkedList& ll) {
    os << ll.getName() << " {";
    Node* current = ll.head;
    if (current == nullptr) {
        os << " <Empty List>";
    }
    while (current != nullptr) {
        if (current != ll.head)
            cout << ",";
        cout << " " << current->stationID << ",";
        cout << " " << current->year << ",";
        cout << " " << current->month << ",";
        cout << " " << current->temperature;
        cout << " " << current->command;
        cout << " " << current->firstYear;
        cout << " " << current->lastYear;
        current = current->next;
     }
    cout << " }";
    return os;
}

主要.CPP

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <ios>
#include <iomanip>
#include <stdlib.h>
#include "LinkedList.hpp"
#include <string>
#include <cmath>
#include "Node.h"
int roundNum (float a) {
    return floor(a + 0.5);
}

using namespace std;
int main(int argc, const char * argv[]) {


    //What I need
    int stationID = 0, year = 0, month = 0, firstYear = 0, lastYear = 0;
    int maxCount = 0;
    int maxNumber = 0;
    int myCount = 0;


bool foundStation = false;
bool foundFirst = false;
bool foundLast = false;
string unknown = "unknown";
double temp = 0.0;
double total = 0.0;
double average = 0.0;
double count = 0.0;
int const CURRENT_YEAR = 2016;
string command = "";
vector<double>avg;
vector<double>mode;
vector<string>final;



LinkedList tempList;
LinkedList queryList;
//Read this file
ifstream tempFile = ifstream("3linetemp.dat");
ifstream queryFile = ifstream("queries.dat");

ofstream outputFile = ofstream("results.dat");

//Linked List for Temperature Data

while (tempFile >> stationID >> year >> month >> temp) {
    try {
    if (year < 1800 || year > CURRENT_YEAR) {throw runtime_error("Error.");}
    if (month < 0 || month > 12) {throw runtime_error("Error.");}
    if (temp == -99.99) {throw runtime_error("Error.");}


    tempList.insertBack(stationID, year, month, temp);
    }
   catch(runtime_error& excpt) {cout << excpt.what() << endl;}
}

//Query Data
while (queryFile >> stationID >> command >> firstYear >> lastYear) {
    queryList.insertBack(stationID, command, firstYear, lastYear);
}

//Get Average and Mode
for (int i = 0; i < queryList.size(); i++) {

   //AVERAGE
    if (queryList.getCommand(i) == "AVG") {
        for (int j = 0; j < tempList.size(); j++) {
            if (queryList.getStationID(i) == tempList.getStationID(j)) { foundStation = true;
                if (tempList.getYear(j) >= queryList.getFirstYear(i)) { foundFirst = true;
                    if (tempList.getYear(j) <= queryList.getSecondYear(i)) { foundLast = true;
                        total += tempList.getTemp(j);
                        count++;
                    }
                }
            }
        }
        if (foundStation == false ||foundFirst == false || foundLast == false) /*Indicates no matching stationID*/ {final.push_back(unknown);}
        else {
            foundStation = false;
            foundFirst = false;
            foundLast = false;
            average = total/count;
            final.push_back(to_string(average));
            average = 0.0;
            total = 0.0;
            count = 0.0;
        }
    }
    //MODE
    //Get possible modes
    if (queryList.getCommand(i) == "MODE") {
        for (int j = 0; j < tempList.size(); j++) {
            if (queryList.getStationID(i) == tempList.getStationID(j)) { foundStation = true;
                if (tempList.getYear(j) >= queryList.getFirstYear(i)) { foundFirst = true;
                    if (tempList.getYear(j) <= queryList.getSecondYear(i)) { foundLast = true;

                        int a = roundNum(tempList.getTemp(j));
                        mode.push_back(a);
                }
            }
        }
    }      //If you can't find station ID
        if (foundStation == false || foundFirst == false || foundLast == false) {final.push_back(unknown);}
        //Find Mode
        else {
            foundStation = false;
            foundFirst = false;
            foundLast = false;
            auto minmax = std::minmax_element(std::begin(mode), std::end(mode));
            int max = *(minmax.second);
            for (int i = 0; i <= max; i++) {
                myCount = ::count(mode.begin(), mode.end(), i);
            if (maxCount < myCount) {
                maxCount = myCount;
                maxNumber = i;
            }
        }
        final.push_back(to_string(maxNumber));
        }
    }
}

cout << "File created." << endl;

  //Make Results File
    for (int i = 0; i < queryList.size(); i++) {
         outputFile << queryList.getStationID(i) << " " <<    queryList.getFirstYear(i) << " " << queryList.getSecondYear(i)  << " " << queryList.getCommand(i) << " " << final.at(i) << endl;
}

for (int i = 0; i < final.size(); i++) {
    cout << final.at(i) << endl;
}
}

节点.H

#include "LinkedList.hpp"
#include "Temperature.hpp"
#include "Query.hpp"
#include "Node.h"
struct Node {
    int stationID, year, month, firstYear, lastYear;
    std::string command;

    double temperature;
    double value = 0;;
    Node* next = nullptr;

     //Temp Node
    Node(int stationID, int year, int month, double temperature) :  stationID(stationID), year(year), month(month), temperature(temperature) {}
    //Query Node
    Node (int stationID, std::string command, int firstYear, int lastYear) : stationID(stationID), command(command), firstYear(firstYear), lastYear(lastYear) {}

    Node() : stationID(0), year(0), month(0), temperature(0), next(nullptr) {}

};

 #endif /* Node_h */

最佳答案

我发现显示的代码存在多个问题。但是,由于显示的代码无法满足 minimal, complete, and verifiable example 的要求坠机的原因极有可能是其他原因。但是,我认为以下错误之一很可能是导致崩溃的未定义行为的原因,并且由于您“感谢任何建议”,因此这可以作为有效答案:

  1. insertBack() 无法将 newNode->next 初始化为 nullptr。如果 Node 的构造函数默认不初始化它,这将导致 tail 节点上的 next 指针未初始化。编辑:您发布了额外的代码,显示 next 是默认初始化的。

  2. 复制构造函数无法将 headtail 初始化为 nullptr。默认构造函数也无法做到这一点。

我怀疑您在复制构造或默认构造的列表上调用 insertBack() 而导致崩溃,其 tail 指针不是初始化,如上所述。如果是这样,这将是一个教科书示例,说明为什么当 C++ 程序在特定行崩溃时,并不一定意味着这是错误所在。

但是,为了确认观察到的未定义行为的原因,仍然有必要查看 minimal, complete, and verifiable example .

附言复制构造函数和赋值运算符是否应该复制实际列表也不清楚。如果是这样,那么不这样做将是另一个错误。

关于c++ - 链表 - EXC_BAD_ACCESS。我认为该错误是因为我错误地删除了一个节点,但我将不胜感激任何建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38689772/

相关文章:

c++ - 在 C++ 中按行打乱二维数组

python - 如何在 Python 中正确合并重叠的日期时间范围

ios - 在 View 之间来回切换时 EXC_BAD_ACCESS 崩溃

ios - 核心数据获取上的 EXC_BAD_ACCESS(code=1, address=0x10)

c++ - 启用默认初始化列表构造函数

c++ - 如何在保留选择的同时刷新 QSqlTableModel?

list - 输出一个元素我想要的次数

macos - NSOutlineTableView 最后一个元素后崩溃

python - 如何在不同的平台/技术中使用经过训练的神经网络?

无法打印字符串单链表的内容