gpt4 book ai didi

使用复制构造函数时 C++ 程序崩溃,动态内存可能是罪魁祸首?

转载 作者:行者123 更新时间:2023-11-28 02:40:46 25 4
gpt4 key购买 nike

对于这个程序,我创建了一个名为 Map 的类,它通过存储一个名为 MapItem 的结构来充当链表。我注意到的是,当我调用复制构造函数并传入其中没有 MapItems 的 Map 对象时,程序不会崩溃。但是,如果我调用复制构造并传入其中包含 MapItems 的 Map 对象,程序就会崩溃。因此,我认为问题可能出在我在下面附加的添加函数上,或者可能出在我的析构函数上,因为当我注释掉它起作用的析构函数时。代码粘贴在下面并尽可能保持最少。谢谢。

map .h

#include <iostream>
using namespace std;

template <class keyType, class valueType>
struct MapItem
{
keyType key;
valueType value;
MapItem<keyType, valueType> *prev, *next;
};

template <class keyType, class valueType>
class Map
{
public:
Map(); // constructor for a new empty map
Map (const Map<keyType, valueType> & other); //constructor for a new map that is intialized with the values of other
~Map (); // destructor
void add (const keyType &key, const valueType &value);
/* Adds a new association between the given key and the given value.
If the key already has an association, it should do nothing.
*/
private:
/* The head and tail of the linked list you're using to store
all the associations. */
MapItem <keyType, valueType> *head, *tail;
int sizeList; //size of the list
int position; //key-value pair we are looking at, can be from 1 - sizeList using next() and first() function
};

map .cpp

#include "Map.h"

template <class keyType, class valueType>
Map<keyType, valueType>::Map()
{
sizeList = 0; //set the size to 0
position = 1; //position is from 1 -> sizeList
head = NULL; //head points to NULL
tail = NULL; //tail points to NULL
}

template <class keyType, class valueType>
Map<keyType, valueType>::Map(const Map<keyType, valueType> &other) //copy constructor
{
head = NULL;
tail = NULL;
sizeList = other.sizeList; //assign the same size (shallow copy)
position = other.position; //assign the same position (shallow copy)
}

template <class keyType, class valueType>
Map<keyType, valueType>::~Map()
{
struct MapItem<keyType, valueType> *temp; //create temp variable to hold which item we are looking at in the list
temp = head; //start at the head

for(int i = 1; i <=sizeList; i++)
{
MapItem<keyType, valueType> *next = temp->next;

delete temp; //delete memory to pointed by temp

if(i != sizeList) //if we are not at the last node
temp = next;
}
}

template <class keyType, class valueType>
void Map<keyType, valueType>::add(const keyType &key, const valueType &value)
{
struct MapItem<keyType, valueType> *newItem; //create pointer to new map item

if(sizeList == 0) //if linked list is empty, make newItem the HEAD
{
newItem = new MapItem<keyType, valueType>; //dynamically allocate a new item on the heap
newItem->key = key; //assign the key
newItem->value = value; //assign the value

sizeList++; //increment size
head = newItem; //set the HEAD of the list to newItem
tail = newItem; //set the TAIL of the list to newItem
newItem->prev = head; //previous item is the head (itself)
newItem->next = head; //next item is the head (itself)
}
else //if the linked list is not empty, add it in
{
struct MapItem<keyType, valueType> *temp = head; //store the first element in the linked list in temp variable

if(sizeList == 1) //if there is only one element in the list, check if they equal eachother
{
if(head->key != key)
{
newItem = new MapItem<keyType, valueType>; //dynamically allocate a new item on the heap
newItem->key = key; //assign the key
newItem->value = value; //assign the value

tail = newItem; //assign newItem as the TAIL
head->next = tail; //assign the next of HEAD to the new map item
head->prev = tail; //assign the previous of HEAD as the newItem (tail)
tail->prev = head; //assign head to PREV of newItem (tail)
tail->next = head; //assign HEAD to NEXT of newItem (tail)
sizeList++; //increment size of list
}
}
else
{
bool sameKey = false; //boolean value to check if the same key already exists, and if it does it will stop the loop
int i = 1; //which item we are looking at in the list

while(i <= sizeList && !sameKey) //while not past the end of the list, keep checking if a similar key exists
{
if(temp->key == key)
sameKey = true;
else
{
temp = temp->next; //go to the next map item
i++;
}
}

if(!sameKey) //if the same key has not been found
{
newItem = new MapItem<keyType, valueType>; //dynamically allocate a new item on the heap
newItem->key = key; //assign the key
newItem->value = value; //assign the value

tail->next = newItem;
newItem->prev = tail;
newItem->next = head;
tail = newItem;
head->prev = tail;
sizeList++;
}
}
}
}

测试.cpp

#include "Map.cpp"


int main()
{
Map<int, int> b;
b.add(1, 1); //if this line is commented out with the destructor intact, then the copy constructor call below works. if this line is NOT commented out with the destructor intact, the program crashes.
Map<int, int> a(b);

system("PAUSE");
return 0;
}

最佳答案

您的析构函数信任成员变量并尝试删除那么多项目。

但是您的复制构造函数使它们与数据量不一致,因为它从不复制任何实际数据。

template <class keyType, class valueType>
Map<keyType, valueType>::Map(const Map<keyType, valueType> &other) //copy constructor
{
head = NULL; // now there are zero items in the list
tail = NULL;
sizeList = other.sizeList; // this is a lie, really there are zero items
position = other.position;
}

当您复制一个空列表时,您会意外地将 sizeList 设置为正确的值,因此没有任何失败。

关于使用复制构造函数时 C++ 程序崩溃,动态内存可能是罪魁祸首?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26078211/

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