簡體   English   中英

C++:如何糾正我的代碼的讀取訪問沖突

[英]C++: How do I correct the read access violation that my code does

我是 C++ 的初學者,並且一直在嘗試自己解決一些問題。 我應該為 function 編寫代碼,該代碼接受指向某個 object、go 的指針向量,然后從列表中刪除無效日期。 到目前為止,在測試時,我不斷收到一條錯誤消息:“拋出異常:讀取訪問沖突”,過去幾天我一直在嘗試查找錯誤,但無濟於事。

這是我的代碼:

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;

class Reminder
{
private:
    int m_day;
    int m_month;
    string m_description;
    bool value;

public:

    Reminder(int day, int month, string description) : m_day(day), m_month(month), m_description(description)
    {

    }

    string toString()
    {
        stringstream sin;
        sin << m_month << "/" << m_day << ": " << m_description<<endl;
        return sin.str();
    }

    int getDay()
    {
        int day = m_day;
        return day;
    }

    int getMonth()
    {
        int month = m_month;
        return month;
    }



};

vector<Reminder*> removeInvalidDate(vector<Reminder*>& list)
{
    for (int count = 0; count < list.size(); count++)
    {
        if ((list[count]->getDay() < 1) || (list[count]->getDay() > 31))
            delete list[count];
        if ((list[count]->getMonth() < 1) || (list[count]->getMonth() > 12))
            delete list[count];
        else
            ;
    }

    return list;
}

int main()
{
    Reminder reminder1(7, 16, "Final Exam Due");
    Reminder reminder2(7, 4, "Independence Day Holiday");
    Reminder reminder3(1, 1, "Start of the New Year");
    Reminder reminder4(7, 30, "My Birthday");
    Reminder reminder5(1, -9, "Impossible Day1");
    Reminder reminder6(0, 0, "Impossible Day0");
    Reminder reminder7(0, 35, "Impossible day3");
    Reminder reminder8(13, 0, "Impossible");

    Reminder* pRe;
    pRe = new Reminder(reminder1);

    vector<Reminder*> list;

    list.push_back(pRe);

    pRe = new Reminder(reminder2);
    list.push_back(pRe);

    pRe = new Reminder(reminder3);
    list.push_back(pRe);

    pRe = new Reminder(reminder4);
    list.push_back(pRe);

    pRe = new Reminder(reminder5);
    list.push_back(pRe);

    pRe = new Reminder(reminder6);
    list.push_back(pRe);

    pRe = new Reminder(reminder7);
    list.push_back(pRe);

    pRe = new Reminder(reminder8);
    list.push_back(pRe);

    removeInvalidDate(list);

    return 0;
}

我認為問題在於設置和傳遞向量或 class 構造函數之一。

如果日期和月份都無效,您將刪除 list[count] 兩次

if ((list[count]->getDay() < 1) || (list[count]->getDay() > 31))
    delete list[count];
if ((list[count]->getMonth() < 1) || (list[count]->getMonth() > 12))
    delete list[count];

我認為問題在於設置和傳遞向量或 class 構造函數之一。

好吧,你可以檢驗這兩個假設。 你真的應該這樣做!

首先,您可以通過簡化代碼以使用vector<int>來測試您的構造函數是否導致問題。 只需說 integer 值是日期,暫時忽略月份部分。

其次,您可以使用最簡單的代碼設置最小向量 - 並且只需一個元素。 或零元素。 然后重新添加元素,直到問題再次出現。

這種工作,測試你對代碼的理解,是完全正常的,也是一個好習慣。

這些假設都不能解決您當前的問題,但我鼓勵您返回 go 並無論如何都要這樣做。

這段代碼

    if ((list[count]->getDay() < 1) || (list[count]->getDay() > 31))
        delete list[count];
    if ((list[count]->getMonth() < 1) || (list[count]->getMonth() > 12))
        delete list[count];
    else
        ;

有兩個主要問題。 首先是布局表明您打算

    if (X)
        A;
    elif (Y)
        B;
    else
        ;

但是 C++沒有elif 如果您不想兩次刪除相同的元素,則應該類似於

    if ((list[count]->getDay() < 1) || (list[count]->getDay() > 31))
    {
        delete list[count];
        continue;
    }
    if ((list[count]->getMonth() < 1) || (list[count]->getMonth() > 12))
    {
        delete list[count];
        continue;
    }

(或if () {... } else if () {... }或其他)。

第二個也是更嚴重的問題是delete list[count]不是從 C++ 中的任何容器中刪除元素的方式。 這大致就是你在 Python 中的做法。 但是在 C++ 中,在delete list[count]之后,元素list[count]仍然存在,但它是指向您剛剛delete -d 的存儲的懸空指針,並且可能永遠不會被合法地取消引用。 由於您要做的下一件事是取消引用它(用於月份檢查),這會導致您的讀取訪問沖突。

任何好書都會告訴您std::vector::erase是如何從向量中刪除元素的方式,並且您應該更喜歡std::remove_if ,並且您應該避免在容器中存儲(擁有)原始指針第一名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM