我试图用c ++创建一个动态字符串数组.当我尝试将动态字符串数组的内容显示到控制台时,我收到此错误:
Exception thrown at 0x0FD670B6 (msvcp140d.dll) in Assignment4.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD.
这是我的代码:
DynamicStringArray.h
#pragma once #include "stdafx.h" #include#include using namespace std; class DynamicStringArray { public: DynamicStringArray(); DynamicStringArray(DynamicStringArray &array); ~DynamicStringArray(); int getSize(); void displayContents(); void addEntry(const string &addElement); string getEntry(int index); int deleteEntry(const string &deleteElement); private: string *dynamicArray; int size; };
DynamicStringArray.cpp
#include "stdafx.h" #include "DynamicStringArray.h" #include#include using namespace std; DynamicStringArray::DynamicStringArray() { dynamicArray = NULL; size = 0; } DynamicStringArray::DynamicStringArray(DynamicStringArray &array) { if (dynamicArray != NULL) { size = 0; delete [] dynamicArray; dynamicArray = NULL; } size = array.getSize(); dynamicArray = new string[size]; for (int i = 0; i < size; i++) dynamicArray[i] = array.dynamicArray[i]; } DynamicStringArray::~DynamicStringArray() { cout << "In destructor." << endl; delete [] dynamicArray; dynamicArray = NULL; } int DynamicStringArray::getSize() { return size; } void DynamicStringArray::displayContents() { if (size != 0) for (int i = 0; i < size; i++) cout << "Item-" << i << ": " << dynamicArray[i] << endl; else cout << "Array is empty." << endl; } void DynamicStringArray::addEntry(const string &addElement) { string *temp = new string[size + 1]; for (int i = 0; i < size; i++) temp[i] = dynamicArray[i]; temp[size] = addElement; size++; delete [] dynamicArray; dynamicArray = temp; delete[] temp; } string DynamicStringArray::getEntry(int index) { if ((index >= 0) && (index < size)) { return dynamicArray[index]; } return NULL; } int DynamicStringArray::deleteEntry(const string &deleteElement) { if(size == 0) { return false; } for (int i = 0; i < size; i++) { if (dynamicArray[i] == deleteElement) { string *temp = new string[size - 1]; for (int x = 0; x < size - 1; ++x) { if (x < i) temp[x] = dynamicArray[x]; else temp[x] = dynamicArray[x + 1]; } delete[] dynamicArray; dynamicArray = temp; delete[] temp; --size; return true; } } return false; }
主要:
int main() { DynamicStringArray dsArray1; cout << "dsArray1.displayContents():" << endl; dsArray1.displayContents(); // Should indicate array is empty cout << "Display dsArray1.getSize()= " << dsArray1.getSize() << endl; dsArray1.addEntry("Entry-A"); dsArray1.displayContents(); dsArray1.addEntry("Entry-B"); dsArray1.displayContents(); dsArray1.addEntry("Entry-C"); dsArray1.displayContents(); return 0; }
谁能告诉我我做错了什么.我该如何解决这个问题?
请注意,所有这些都已经可以利用
std::vector
.该的std ::向量类是动态数组类,C++提供,并有很少或几乎没有理由让什么是提供给您的自制版本.
话虽如此,一个明显的问题是你的拷贝构造函数是不正确的.它dynamicArray
是未初始化的,但你在这里使用它:
if (dynamicArray != NULL)
无法保证价值dynamicArray
.修复是删除复制构造函数中的整个代码块:
if (dynamicArray != NULL) { size = 0; delete [] dynamicArray; dynamicArray = NULL; }
由于复制构造函数构造了一个全新的对象,因此没有理由对NULL指针进行"预测试",从而进行不必要的工作.请记住,该对象不存在,因此没有什么可以做的初步.
第二个问题是你delete [] temp;
在addEntry
和deleteEntry
函数中发出了一个调用.删除这些行,因为您要释放刚刚分配给的内存dynamicArray
.
第三个问题是您缺少用户定义的赋值运算符.赋值运算符具有以下签名,您需要提供实现:
DynamicStringArray& operator=(const DynamicStringArray& );
如果没有此函数,则在两个对象超出范围时,将a分配DynamicStringArray
给另一个DynamicStringArray
将导致内存泄漏和内存的双重释放.
一种实现可以使用复制/交换习语:
#include//... DynamicStringArray& DynamicStringArray::operator=(const DynamicStringArray& rhs) { DynamicStringArray temp(rhs); std::swap(temp.dynamicArray, dynamicArray); std::swap(temp.size, size); return *this; }
另一个问题是:
string DynamicStringArray::getEntry(int index) { if ((index >= 0) && (index < size)) { return dynamicArray[index]; } return NULL; // <-- Undefined behavior if this is done }
为std::string
对象分配NULL 是未定义的行为.要么返回空字符串,要么在索引超出范围时抛出异常.
总之,我强烈建议您在设计必须实现正确复制语义的类时阅读规则3.