C++ 查找链接列表中的损坏

C++ 查找链接列表中的损坏,c++,c,C++,C,我今天面试了一个开发人员的职位,被问到一个有趣的技术问题,我不知道答案。我会在这里问它,看看是否有人能为我的好奇心提供一个解决方案。这是一个多部分的问题: 1) 给您一个包含100个元素(整数和指向下一个节点的指针)的单链接列表,是否找到一种方法来检测链接列表中途是否出现中断或损坏?你可以用链表做任何事情。请注意,您必须在列表中执行此操作,因为它正在迭代,这是在您意识到列表有任何问题之前进行的验证 假设链表中的断点位于第50个元素,则整数甚至指向下一个节点(第51个元素)的指针可能指向垃圾值,而

我今天面试了一个开发人员的职位,被问到一个有趣的技术问题,我不知道答案。我会在这里问它,看看是否有人能为我的好奇心提供一个解决方案。这是一个多部分的问题:

1) 给您一个包含100个元素(整数和指向下一个节点的指针)的单链接列表,是否找到一种方法来检测链接列表中途是否出现中断或损坏?你可以用链表做任何事情。请注意,您必须在列表中执行此操作,因为它正在迭代,这是在您意识到列表有任何问题之前进行的验证


假设链表中的断点位于第50个元素,则整数甚至指向下一个节点(第51个元素)的指针可能指向垃圾值,而垃圾值不一定是无效地址


2) 请注意,如果链接列表中存在损坏,您将如何最大限度地减少数据丢失?

如果您在设计时知道损坏可能会成为一个关键问题,则可以在节点数据结构中添加一个“神奇值”作为字段,以识别某些数据是否可能是节点。甚至可以在内存中搜索节点

或者将某些链接信息加倍,即在每个节点的下一个节点之后存储该节点的地址,这样,如果一个链接断开,您就可以恢复


我看到的唯一问题是必须避免分段错误。

由于元素数(100)已知,第100个节点必须包含空指针。如果是,则具有某种良好概率的列表是有效的(例如,如果第99个节点已损坏并指向某个全零的内存位置,则无法保证这一点)。否则,会出现一些问题(这可以作为事实返回)


upd:此外,如果给定指针,也可以在每个步骤中查看
delete
将使用的一些结构,但是由于使用
delete
本身在任何意义上都不安全,这将是特定于实现的。

对于第一部分,重载新操作符。当分配新节点时,在节点前后分配一些额外的空间,并在那里放置一些已知值。在遍历中,可以检查每个节点是否在已知值之间。

要测试“损坏”的整数,您需要知道有效值的范围。否则,无法确定任何给定(有符号)整数中的值是否无效。因此,假设您对int进行了有效性测试,那么在迭代到下一个元素之前,您将始终检查该值

测试损坏的指针更为棘手——首先,您需要在尝试取消引用下一个元素之前检查指针的值,并确保它是有效的堆地址。这将避免分段错误。下一件事是验证指针指向的实际上是一个有效的链表节点元素——这有点棘手?也许将指针反引用到列表元素类/结构中,并测试int和“next”指针的有效性,如果它们也很好,那么可以非常确定前一个节点也很好


在2)上,发现损坏的节点后,[如果下一个指针损坏],您应该立即将上一个节点的“下一个指针”设置为“NULL”,将其标记为列表的结尾,并记录错误等。如果损坏只是整数值,而不是“下一个”元素指针,然后,您应该从列表中删除该元素,并将前面和后面的节点链接在一起,因为在这种情况下,不需要丢弃列表的其余部分

如果可以对链表执行任何操作,则可以计算每个元素的校验和并将其存储在元素本身上。这样,即使是元素上的一个位错误,也可以检测损坏


为了减少数据丢失,也许你可以考虑在前一个元素中存储NEXPTR,这样,如果你的当前元素被破坏了,你总是可以找到前一个元素的位置。

< P>这是一个简单的问题,并且有几种可能的答案。每种方法都权衡了健壮性和效率。由于增强鲁棒性是问题提出的先决条件,因此有一些解决方案既牺牲时间(列表遍历速度,以及节点插入和删除速度),也牺牲空间(每个节点存储的额外信息)。现在的问题是,这是一个长度为100的固定列表,在这种情况下,链表的数据结构是最不合适的。为什么不让谜题变得更具挑战性一点,并说列表的大小是未知的

“哪一个不一定是无效地址”除非C#的不安全关键字或某些本机互操作(p/Invoke,JNI),否则在C#或Java中如何有指向无效地址的指针?您首先必须定义“corrupt”。用C#和Java标记它真的正确吗?它们没有指针(除非编写不安全的C#代码),引用不能指向无效地址。这个问题在C或C++中更具意义。对链表中存储的整数值有什么限制吗?“你如何最小化数据丢失?”——通过编写已经工作并已经测试过的代码……“你必须避免分段错误”——你必须一直在,不仅在这个特殊的情况下————是的,但是,如果你不能依赖指针的有效性,那么避免分段错误就更难了。这在很多层面上都是错误的。中间的腐败节点怎么样?你只是在内存中“冲浪”,就像没有明天一样,而实际上它都是垃圾,只有运气好,你可能会留在内存中,你才被允许访问,只是打赌在100次迭代后,你将有值
0
作为指针。这完全失败了。不正确