双向链表等差数列检测报错:VS2015空指针访问违例异常求助
修复链表等差数列检测的空指针异常
嘿,你的代码里有几个明显的问题导致了这个读取访问违例,我来帮你拆解并修复:
问题根源
- 最后一个节点的空指针访问:在
while(p != NULL)循环里,当p走到链表最后一个节点时,p->pNext是nullptr,这时候q = p->pNext就是空指针,再去访问q->info肯定会崩溃。 - 未处理边界情况:如果链表是空的,或者只有1个节点,你直接访问
l.pHead->pNext->info会直接炸掉——要么pHead本身是nullptr,要么pNext是空的。 - 逻辑判断有漏洞:你的
flag变量只要碰到一对符合差值的节点就设为1,但如果后面出现不符合的节点,flag不会变回0,这样会误判(比如前两个符合,后面不符合,函数还是返回1)。
修复后的完整代码
struct NODE { int info; NODE *pNext; NODE *pPrev; }; struct LIST { NODE *pHead; NODE *pTail; }; void Init(LIST &l) { l.pHead = NULL; l.pTail = NULL; } NODE *getNode(int x) { NODE *p = new NODE; if (p == NULL) return NULL; p->info = x; p->pNext = NULL; p->pPrev = NULL; return p; } void AddTail(LIST &l, NODE *p) { if (l.pHead == NULL) l.pHead = l.pTail = p; else { p->pPrev = l.pTail; l.pTail->pNext = p; l.pTail= p; } } int isEmpty(LIST l) { return l.pHead == NULL; } int testArithmetic(LIST &l) { // 处理空链表或单个节点的情况:这里默认返回1(认为是等差数列),你可以根据需求改0 if (isEmpty(l) || l.pHead->pNext == NULL) { return 1; } // 先计算初始公差 int d = l.pHead->pNext->info - l.pHead->info; NODE *p = l.pHead; // 循环条件改成p->pNext != NULL,确保每次q都是有效节点 while (p->pNext != NULL) { NODE *q = p->pNext; // 只要有一对不符合,直接返回0,不用继续循环 if (q->info - p->info != d) { return 0; } p = p->pNext; } // 所有相邻节点都符合公差,返回1 return 1; }
核心修复说明
- 边界防护:先检查链表是否为空或只有一个节点,避免直接访问空指针的成员。
- 循环条件优化:把
while(p != NULL)改成while(p->pNext != NULL),这样每次循环里q都不会是空指针,彻底解决访问违例的问题。 - 逻辑严谨性提升:一旦发现不符合的节点对,立刻返回0,不需要遍历完整个链表;如果全部符合,最后返回1,避免了原代码中
flag变量的误判问题。
如果你的需求里认为空链表或单个节点不算等差数列,只需要把对应的返回值改成0就行啦。
内容的提问来源于stack exchange,提问作者KhaNguyen
相关产品推荐
相关产品推荐

