当前位置:  开发笔记 > 编程语言 > 正文

异常错误:访问冲突读取位置0xDDDDDDDD

如何解决《异常错误:访问冲突读取位置0xDDDDDDDD》经验,为你挑选了1个好方法。

我试图用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;
}

谁能告诉我我做错了什么.我该如何解决这个问题?



1> PaulMcKenzie..:

请注意,所有这些都已经可以利用 std::vector.该的std ::向量类是动态数组类,C++提供,并有很少或几乎没有理由让什么是提供给您的自制版本.


话虽如此,一个明显的问题是你的拷贝构造函数是不正确的.它dynamicArray是未初始化的,但你在这里使用它:

if (dynamicArray != NULL)

无法保证价值dynamicArray.修复是删除复制构造函数中的整个代码块:

if (dynamicArray != NULL)
{
    size = 0;
    delete [] dynamicArray;
    dynamicArray = NULL;
}

由于复制构造函数构造了一个全新的对象,因此没有理由对NULL指针进行"预测试",从而进行不必要的工作.请记住,该对象不存在,因此没有什么可以做的初步.


第二个问题是你delete [] temp;addEntrydeleteEntry函数中发出了一个调用.删除这些行,因为您要释放刚刚分配给的内存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.


`addEntry`中的赋值都是`std :: string`s,所以它们很好(实现`operator =`仍然可能是一个好主意).问题出在最后一行`delete [] temp;`
推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有