2016-08-01 4 views
1
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.Связанный список - EXC_BAD_ACCESS. Я считаю ошибку, потому что я неправильно удалил узел, но я был бы признателен за любые советы

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; 
} 

main.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; 
} 
} 

node.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 */ 
+0

1) Где программа 'main', чтобы увидеть, как вы используете связанный список? 2) Используете ли вы отладчик для отладки вашей программы? 3) Вы должны были выполнить единичную проверку базовых функций связанного списка, например, вставка элемента ** до того, как ** перейдет к написанию всего этого класса. На этапе, где ваш код сейчас, вставка в список не должна была быть проблемой *, если класс был проверен на единицу *. – PaulMcKenzie

+0

Ваш конструктор копирования и оператор присваивания полностью ошибочны. Конструктор копирования не инициализирует все элементы указателя, и я не вижу фактического копирования связанного списка с передачей в 'this'. То же самое с оператором присваивания - реального копирования не происходит, но какой-то минимальный код «здесь меня получил». – PaulMcKenzie

ответ

0

Я вижу несколько проблем с показанным кодом. Однако, поскольку показанный код не отвечает требованиям minimal, complete, and verifiable example, существует небольшая вероятность того, что причиной сбоя является что-то другое. Тем не менее, я думаю, что это, вероятно, что одна из следующих ошибок отвечает за непредсказуемое поведение, которое приводит к аварии, и так как вы «признателен за любые советы», это право будет как действительный ответ:

  1. insertBack() терпит неудачу для инициализации newNode->next до nullptr. Если конструктор Node не инициализирует его по умолчанию, это приведет к неинициализированному указателю next на узле tail. EDIT: вы добавили дополнительный код, который показывает, что next инициализируется по умолчанию.

  2. Конструктор копирования не может инициализировать head и tail до nullptr. Конструктор по умолчанию также не может этого сделать.

Я подозреваю, что вы видите аварии в результате вызова insertBack() на копию возведенных или списка по умолчанию, возведенных, чей tail указатель не был инициализирован, как описано выше. Если это так, это будет пример учебника о том, почему при сбое программы на C++ в определенной строке это не обязательно означает, что это ошибка.

Но, тем не менее, чтобы подтвердить причину наблюдаемого неопределенного поведения, необходимо будет увидеть minimal, complete, and verifiable example.

P.S. Также неясно, должен ли копировать-конструктор и оператор присваивания делать копию фактического списка. Если это так, то отказ сделать это будет другой ошибкой.

+0

Спасибо. Я прикрепил свой файл main.cpp и my node.h. Я считаю, что это будет соответствовать требованиям. Я инициализировал свой Node * рядом с nullptr в моем заголовочном файле. Нужно ли это делать в моей функции insertBack()? – jr27

+0

Нет, инициализации по умолчанию будет достаточно.Однако ваш пример, по крайней мере, является «минимальной» и «полной» частью. Большая часть опубликованного кода, очевидно, совершенно не имеет отношения к ошибке, поэтому это не соответствует «минимальной» части. «Полное» требование означает, что любой может компилировать и выполнять опубликованный код для воспроизведения проблемы. Показанный код по-прежнему терпит неудачу, по-разному, для удовлетворения «полного» требования. Показанный пример не является ** полным **, если в нем не содержится все, что кому-либо нужно, чтобы ** проверить ** и воспроизвести заданный вопрос. –