gpt4 book ai didi

c++ - 如何在访问指针值时保护应用程序免受读取访问冲突?

转载 作者:行者123 更新时间:2023-11-28 04:22:04 24 4
gpt4 key购买 nike

我创建了一些类似链的结构,其中一个对象具有指向链中下一个和上一个对象的指针。下面的代码遍历整个链,查找参数中指定的值并删除匹配元素(如果存在)。

void List::removeElementByValue(int value)
{
ListMember* nextElem = this->firstValue;
while (nextElem) {
if (nextElem == NULL || nextElem == nullptr) {
break;
}

if (nextElem->value == value) {
if (nextElem->prevValue)
(nextElem->prevValue)->nextValue = nextElem->nextValue;
if (nextElem->nextValue)
(nextElem->nextValue)->prevValue = nextElem->prevValue;
delete nextElem;
this->count--;
return;
}
nextElem = nextElem->prevValue;
}
}

问题是:当我试图从链中删除不存在的值时出现此错误。

Exception thrown: read access violation. nextElem was 0xCDCDCDCD.

在那种情况下,函数应该什么都不做。它发生在这一行:

 if (nextElem->value == value) {

如您所见,我使用了多种方法来检查 nextElem 是否正确,但我仍然收到此错误。有什么方法可以防止这种情况发生?

最佳答案

if (nextElem == NULL || nextElem == nullptr)

while (nextElem) 为真时,这将始终为假。

nextElem = nextElem->prevValue;

这需要使用nextValue而不是prevValue

但是,最重要的是,如果在列表的第一个元素中找到 value,则您不会更新 this->firstValue,因此您最终删除了 firstValue 并让它指向无效内存。

试试这个:

void List::removeElementByValue(int value)
{
ListMember* elem = this->firstValue;
while (elem) {
if (elem->value == value) {
if (elem->prevValue)
elem->prevValue->nextValue = elem->nextValue;
if (elem->nextValue)
elem->nextValue->prevValue = elem->prevValue;

// ADD THIS!!!
if (elem == this->firstValue)
this->firstValue = elem->nextValue;

delete elem;
this->count--;
return;
}

elem = elem->nextValue; // NOT prevValue!
}
}

更好的解决方案是首先不要手动实现链表。使用标准 std::list取而代之的是容器,让它为您完成所有艰巨的任务。

#include <list>

class List
{
private:
std::list<int> values;
...
};

...

#include <algorithm>

void List::removeElementByValue(int value)
{
auto iter = std::find(values.begin(), values.end(), value);
if (iter != values.end())
values.erase(iter);
}

关于c++ - 如何在访问指针值时保护应用程序免受读取访问冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55249908/

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