异常错误:访问冲突读取位置 0xDDDDDDDD
Posted
技术标签:
【中文标题】异常错误:访问冲突读取位置 0xDDDDDDDD【英文标题】:Exception Error : Access violation reading location 0xDDDDDDDD 【发布时间】:2015-12-18 03:29:59 【问题描述】:我正在尝试在 C++ 中创建一个动态字符串数组。当尝试将我的动态字符串数组的内容显示到控制台时,我收到此错误:
Exception thrown at 0x0FD670B6 (msvcp140d.dll) in Assignment4.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD.
这是我的代码:
DynamicStringArray.h
#pragma once
#include "stdafx.h"
#include <string>
#include <iostream>
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 <string>
#include <iostream>
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::string>
?
【参考方案1】:
请注意,所有这些都可以通过使用
std::vector<std::string>
。 std::vector 类是 C++ 提供的动态数组类,几乎没有理由制作可供您使用的自制版本。
话虽如此,一个明显的问题是您的复制构造函数不正确。 dynamicArray
未初始化,但您在这里使用它:
if (dynamicArray != NULL)
无法保证dynamicArray
的值是多少。解决方法是删除复制构造函数中的整个代码块:
if (dynamicArray != NULL)
size = 0;
delete [] dynamicArray;
dynamicArray = NULL;
由于复制构造函数构造了一个全新的对象,因此没有理由对 NULL 指针进行“预测试”,从而做不必要的工作。请记住,该对象不存在,因此无需进行任何准备工作。
第二个问题是您在addEntry
和deleteEntry
函数中发出delete [] temp;
调用。删除这些行,因为您正在释放您刚刚分配给 dynamicArray
的内存。
第三个问题是您缺少用户定义的赋值运算符。赋值运算符有如下签名,需要提供实现:
DynamicStringArray& operator=(const DynamicStringArray& );
如果没有这个函数,将DynamicStringArray
分配给另一个DynamicStringArray
将导致内存泄漏和内存的双重释放,当两个对象都超出范围时。
一个实现可以使用copy / swap idiom:
#include <algorithm>
//...
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
使用 NULL 分配 std::string
对象是未定义的行为。要么返回空字符串,要么在索引超出范围时抛出异常。
最后,我强烈建议您在设计必须实现正确复制语义的类时阅读Rule of 3。
【讨论】:
addEntry
中的分配都是std::string
s,所以它们很好(实现operator=
可能仍然是一个好主意)。问题在于最后一行delete[] temp;
@MilesBudnek 我更新了答案以指出addEntry
和deleteEntry
的问题。以上是关于异常错误:访问冲突读取位置 0xDDDDDDDD的主要内容,如果未能解决你的问题,请参考以下文章
DLL代理调用LoadLibrary导致异常:访问冲突读取位置0x00000250
c++错误0x... 处(位于... .exe 中)引发的异常: 0xC0000005: 读取位置 0x...时发生访问冲突?