作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一些类似链的结构,其中一个对象具有指向链中下一个和上一个对象的指针。下面的代码遍历整个链,查找参数中指定的值并删除匹配元素(如果存在)。
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/
我是一名优秀的程序员,十分优秀!