首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设置对象属性时C++内存访问冲突

设置对象属性时C++内存访问冲突
EN

Stack Overflow用户
提问于 2010-11-25 22:04:09
回答 4查看 804关注 0票数 0

我的代码中有一部分无法工作。构建一个基本的链接列表来学习指针。我想我已经把它的大部分都写下来了,但是任何使用我创建的函数(push_back)的尝试都会在为指针设置值时抛出内存访问错误。

不完全确定出了什么问题,因为使用push_front很好,它的工作原理几乎完全相同。

有什么想法吗?

代码:

driver.cpp

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-11-25 22:26:03

根据node的定义,这是一个单链列表。(否则,你也必须包含prevNode)。

因此--操作列表的“回”是不平凡的。要弹出列表的“回”,您需要横过整个列表并识别新的“最后”元素。

你确定你做得对吗?包括处理所有的“极端”案例(比如删除最后一个元素等等)?

最好能发布push_backpop_back的代码。

也许你没有在你的push_frontpop_front中正确地设置push_frontpop_front。除非你试图操纵你的“背部”,否则你可能不会注意到这一点。

同时发布push_frontpop_front的代码。

编辑

好吧,我看到密码了。还有很多错误。

代码语言:javascript
复制
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;
}
票数 1
EN

Stack Overflow用户

发布于 2010-11-25 22:21:20

推方法有错误,因为当你在前面推的时候,你不能控制这个元素是否也是最后一个,当你在最后推的时候也是相似的。它导致你没有连接整个列表,因为开始部分不知道结束部分。我希望这是可以理解的。

另外,pop方法也是错误的--同样的问题。您无法控制列表是否为空

票数 2
EN

Stack Overflow用户

发布于 2010-11-25 22:21:14

当列表为空时,在push_back temp中为NULL。因此,temp->setNextNode(input)失败。您需要区分空列表的特殊情况。

顺便问一下,如果您允许在后面和前面的操作,也许您需要一个双链接的列表?否则,您需要遍历整个列表(可能很大),才能弹出最后一个元素,因为您没有指向前一个元素的“直接”链接。

顺便说一句,你的操作是德克的,不是名单的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4281146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档