2010-11-25 9 views
0

コードの一部がうまく動作しない。ポインタを学ぶための基本的なリンクリストの作成。私は、私はそれの大部分を持っていると思うが、私が作成した関数(push_back)を使用しようとすると、ポインタの値を設定する際にメモリアクセスエラーがスローされます。オブジェクトプロパティを設定中にC++のメモリアクセス違反が発生する

それはほとんど同じ仕事push_frontを、使用することが正常に動作しますので、間違っているかを正確にわかりません。

アイデア? =/

CODE:

driver.cpp

#include <string> 
#include <iostream> 
#include "linklist.h" 
#include "node.h" 

using namespace std; 

// printList function 
// Purpose: Prints each node in a list 
// Returns: None. 
// Pre-Conditions: List must have member nodes. 
// Post-Conditions: None. 
void printList(linklist); 

int main() 
{ 
    linklist grocery; 

    grocery.push_front(new node("milk", "1 gallon")); 
    grocery.push_front(new node("bread","2 loaves")); 
    grocery.push_front(new node("eggs","1 dozen")); 
    grocery.push_front(new node("bacon","1 package")); 
    cout << "First iteration:" << endl; 
    printList(grocery); 
    cout << "----------------------" << endl << endl; 

    grocery.push_front(new node("hamburger","2 pounds")); 
    grocery.push_front(new node("hamburger buns", "1 dozen")); 
    cout << "Second iteration:" << endl; 
    printList(grocery); 
    cout << "----------------------" << endl << endl; 

    node* deleteMe = grocery.pop_front(); 
    delete deleteMe; 
    cout << "Third iteration:" << endl; 
    printList(grocery); 
    cout << "----------------------" << endl << endl; 

    grocery.push_back(new node("orange juice","2 cans")); 
    grocery.push_back(new node("swiss cheeese","1 pound")); 
    cout << "Fourth iteration:" << endl; 
    printList(grocery); 
    cout << "----------------------" << endl << endl; 

    deleteMe = grocery.pop_back(); 
    delete deleteMe; 
    cout << "Fifth iteration:" << endl; 
    printList(grocery); 
    cout << "----------------------" << endl << endl; 

    while (grocery.getNodeCount() != 0) 
    { 
      deleteMe = grocery.pop_front(); 
      cout << "Cleaning: " << deleteMe->getDescription() << endl; 
      delete deleteMe; 
    } 

    system("PAUSE"); 
    return 0; 
} 

void printList(linklist input) 
{ 
    node* temp = input.getFirst(); 
    for (int i = 0; i < (input.getNodeCount()); i++) 
    { 
     cout << temp->getQuantity() << " " << temp->getDescription() << endl; 

     temp = temp->getNextNode(); 
    } 
} 

node.h

#pragma once 
#include <string> 

using namespace std; 

class node 
{ 
public: 
// Default Constructor 
// Values, "none", "none", NULL. 
node(); 

// Parameterized Constructor 
// nextNode initialized NULL and must be explicitly set. 
node(string descriptionInput, string quantityInput); 

// getDescription function 
// Purpose: Returns node description. 
// Returns: string 
// Pre-Conditions: None. 
// Post-Conditions: None. 
string getDescription(); 

// setDescription function 
// Purpose: Sets node description 
// Returns: Void 
// Pre-Conditions: None 
// Post-Conditions: None 
void setDescription(string); 

// getQuantity function 
// Purpose: Returns node quantity. 
// Returns: string 
// Pre-Conditions: None. 
// Post-Conditions: None. 
string getQuantity(); 

// setQuantity function 
// Purpose: Sets node quantity 
// Returns: Void 
// Pre-Conditions: None 
// Post-Conditions: None 
void setQuantity(string); 

// getNextNode function 
// Purpose: Returns pointer to next node in list sequence. 
// Returns: node pointer 
// Pre-Conditions: None. 
// Post-Conditions: None. 
// Note: Not set during initialization. Must be explicitly done. 
node* getNextNode(); 

// setNextNode function 
// Purpose: Sets pointer to next node in list sequence. 
// Returns: None. 
// Pre-Conditions: None. 
// Post-Conditions: None. 
// Note: Not set during initialization. Must be explicitly done. 
void setNextNode(node*); 
private: 
string description; 
string quantity; 
node* nextNode; 
}; 

node.cpp

#include "node.h" 


node::node() 
    :description("none"), 
    quantity("none"), 
    nextNode(NULL) 
    {} 

node::node(string descriptionInput, string quantityInput) 
    :description(descriptionInput), 
    quantity(quantityInput), 
    nextNode(NULL) 
    {} 

string node::getDescription() 
{ 
    return description; 
} 

void node::setDescription(string descriptionInput) 
{ 
    description = descriptionInput; 
} 

string node::getQuantity() 
{ 
    return quantity; 
} 

void node::setQuantity(string quantityInput) 
{ 
    quantity = quantityInput; 
} 

node* node::getNextNode() 
{ 
    return nextNode; 
} 

void node::setNextNode(node* input) 
{ 
    nextNode = input; 
} 

LINKLIST。時間まあ

#pragma once 
#include "node.h" 

class linklist 
{ 
public: 
// Constructor 
// Builds an empty list 
linklist(); 

// push_front function 
// Purpose: Takes node pointer. Places that node at beginning of list. 
// Returns: None 
// Pre-Conditions: None 
// Post-Conditions: None 
void push_front(node*); 

// pop_front function 
// Purpose: Removes first node from list. 
// Returns: Node pointer. NODE IS NOT DESTROYED. 
// Pre-Conditions: List must have a node to remove. 
// Post-Conditions: Node is not destroyed. 
node* pop_front(); 

// getFirst function 
// Purpose: Returns node pointer to first node in list 
// Returns: node pointer 
// Pre-Conditions: List must have a node added. 
// Post-Conditions: None. 
node* getFirst(); 

// push_back function 
// Purpose: Takes node pointer. Places that node at end of list. 
// Returns: None 
// Pre-Conditions: None 
// Post-Conditions: None 
void push_back(node*); 

// pop_back function 
// Purpose: Removes last node from list. 
// Returns: Node pointer. NODE IS NOT DESTROYED. 
// Pre-Conditions: List must have a node to remove. 
// Post-Conditions: Node is not destroyed. 
node* pop_back(); 

// getNodeCount function 
// Purpose: Returns nodeCount 
// Returns: int 
// Pre-Conditions: None. 
// Post-Conditions: None. 
int getNodeCount(); 
private: 
node* firstNode; 
node* lastNode; 
int nodeCount; 
}; 

linklist.cpp

#include "linklist.h" 


linklist::linklist() 
    :firstNode(NULL), 
    lastNode(NULL), 
    nodeCount(0) 
{} 

void linklist::push_front(node* input) 
{ 
    node* temp = getFirst(); 

    input->setNextNode(temp); 

    firstNode = input; 
    nodeCount++; 
} 

node* linklist::pop_front() 
{ 
    node* temp = getFirst(); 

    firstNode = temp->getNextNode(); 

    nodeCount--; 
    return temp; 
} 

node* linklist::getFirst() 
{ 
    return firstNode; 
} 

void linklist::push_back(node* input) 
{ 
    node* temp = lastNode; 

    temp->setNextNode(input); 

    lastNode = temp; 
    nodeCount++; 
} 

node* linklist::pop_back() 
{ 
    node* oldLast = lastNode; 
    node* temp = firstNode; 

    // find second to last node, remove it's pointer 
    for (int i = 0; i < (nodeCount - 1); i++) 
    { 
     temp = temp->getNextNode(); 
    } 
    temp->setNextNode(NULL); 

    lastNode = temp; 

    nodeCount--; 
    return oldLast; 
} 

int linklist::getNodeCount() 
{ 
    return nodeCount; 
} 
+0

フォーマットをクリーンアップすると、私に狂ったようです。 – DivinusVox

+1

コード全体を選択し、1と0のボタンをクリックします。 – Dialecticus

+2

クラッシュが 'push_back'にある場合は、' linklist.cpp'を提供する必要がありますか? – icecrime

答えて

1

nodeの定義によると、それは単一リンクリストです。 (そうでなければ、prevNodeも含める必要があります)。

したがって、あなたのリストの "後ろ"を操作することは自明ではありません。リストの「戻る」をポップするには、リスト全体を横断して新しい「最後の」要素を特定する必要があります。

本当にこれは正しいですか?すべての「極端な」ケース(最後の要素などを削除するようなもの)の処理を含む?

push_backpop_backのコードを投稿するとよいでしょう。

P.S.おそらくpush_frontpop_frontlastNodeを正しく設定していない可能性があります。あなたはあなたの "背中"を操作しようとしていない限り、これに気付かないかもしれません。

push_frontpop_frontのコードも転記してください。

EDIT

さてさて、私はコードを参照してください。そして、多くの誤りがあります。

void linklist::push_front(node* input) 
{ 
    node* temp = getFirst(); 

    input->setNextNode(temp); 

    firstNode = input; 
    nodeCount++; 

    // Missing: 
    if (!temp) 
     lastNode = firstNode; 
} 


node* linklist::pop_front() 
{ 
    node* temp = getFirst(); 

    firstNode = temp->getNextNode(); 

    // Missing: 
    if (!firstNode) 
     lastNode = 0; 

    nodeCount--; 
    return temp; 
} 


void linklist::push_back(node* input) 
{ 
    node* temp = lastNode; 

    // instead of 
    // temp->setNextNode(input); 
    // lastNode = temp; 

    // should be: 
    if (temp) 
     temp->setNextNode(input); 
    else 
     firstNode = input; 

    lastNode = input; 

    nodeCount++; 
} 

node* linklist::pop_back() 
{ 
    node* oldLast = lastNode; 

    if (firstNode == lastNode) 
    { 
     firstNode = 0; 
     lastNode = 0; 
    } else 
    { 
     node* temp = firstNode; 

     // find second to last node, remove it's pointer 
     for (int i = 0; i < (nodeCount - 1); i++) 
     { 
      temp = temp->getNextNode(); 
     } 
     temp->setNextNode(NULL); 

     lastNode = temp; 
    } 

    nodeCount--; 
    return oldLast; 
} 
+0

このコードは、エントリの一番下にあるlinklist.cppで利用できるはずです。 – DivinusVox

+0

これはうれしいことですが、数分前に投稿しました(ただ説明したコードはありません)。 – Gaim

+0

@Gaim:はい、そうです。 +1もしこれはあなたにとって重要: – valdo

1

、リストはpush_backtempで、空でNULLです。したがって、temp->setNextNode(input)は失敗します。空リストの特別な場合を区別する必要があります。ところで

、あなたは両方の背面と前面の操作は、おそらくあなたは、二重リンクリストが必要なことができたら?それ以外の場合は、直前の要素への「直接」リンクがないため、最後の要素をポップするために、(潜在的に巨大な)リスト全体をトラバースする必要があります。

ところで、操作はリストではなく両端キューの操作です。

2

プッシュメソッドでは間違いがあります。フロントを押しているときには、この要素も最後の要素であるかどうかを制御しないため、最後を押しているときも同様です。最初の部分は終わりの部分について知りませんので、あなたは全体のリストを接続していないことが原因です。これが理解できることを願っています。

また、popメソッドも同じ問題です。リストが空の場合は、コントロールしていない

+0

わかりません。私は実装から、push_frontが動作することを知っています。現在のノードの前に新しいノードを配置し、古い最初のノードへのポインタを作成し、リストオブジェクトのfirstNodeエントリを置き換えます。 push_backと同様のことをしようとする - 新しいノードを作成し、既存のlastNodeのNULL nextNode値を実際のアドレスで上書きし、新しい最後のノードを指すようにします。 – DivinusVox

+0

@Divinusvox ti push_frontを試してからpush_backを試してみてください。私が間違っていない場合、リストは一貫性のある状態ではありません。なぜなら、firstNodeが最初に挿入されたポイントを指し、NULLを指しているので、NULLを指している2番目のポインタを指すlastNodeがあります。しかし、最初のノードは2番目のノードを指しません。今はいいですか? – Gaim

+0

@DivinusVoxそれはあなたのリストには2のノード数が設定されていますが、最初からそれを閲覧している場合は、2番目のノードにはアクセスできません。 – Gaim

1
あなたは一backに1個の簡単なエラーを持っているように見えます

:上記の注釈を付けたよう

void linklist::push_back(node* input) 
{ 
    node* temp = lastNode; 

    temp->setNextNode(input); 

    lastNode = temp; //this looks wrong 
    nodeCount++; 
} 

が、私はあなたがlastNode = inputを意味だと思います。

P.S. "exception safety" carefully into accountとする。例外的な中立性/安全性をサポートするために、popルーチンが何も返さず、代わりにpeek()ルーチンと組み合わされることは珍しいことではありません。

+0

これをキャッチしてくれてありがとう。アクセス違反は修正されませんが、この機能を実装できるという問題がありました。 :) – DivinusVox

関連する問題