繁体   English   中英

关于在C ++中的访问冲突?

[英]In regards to access violation in C++?

我必须检查C ++中不同数据结构中的访问冲突。 据我所知,这取决于您使用的编译器。

但是,我想知道为什么当发生访问冲突时,g ++编译器倾向于打印一些无意义的数字? 例如,如果我有int a[10]; 并且我做cout << a[100] << endl; ,它将显示类似49738290的内容,但并不代表任何内容。 它不应该打印null或'\\ 0'之类的东西吗? 我认为,当迭代器超出范围时,使用迭代器也会发生相同的情况。

我认为在Visual Studio中,它不会打印类似49738290的内容。它可能会打印null或\\ 0,有时会导致程序崩溃。 这是什么原因呢?

有编译专家吗?

“不确定行为”表示结果不确定。 什么都可能发生。 您可以获得0。 您可以得到一些正数。 您可以得到一些负数。 否则您的程序可能会崩溃。 每次运行该程序时,您都会得到不同的结果。

对于未定义的行为,您无法期望任何特定的结果或动作会发生。

在C ++中,程序在运行时不知道数组的长度(实际上,它可能不知道它是数组还是指针,当传递给函数时,两者都只是作为地址传递)。 因此,它假定索引是有效的,并根据数据的大小查看数组的第100个元素。 从技术上讲,发生的事情是不确定的-该操作是非法的,因此该应用程序可以执行任何操作。

大多数编译器/ OS实际发生的情况-它会根据数组的起始位置查看数组中的第100个整数。 根据数组在内存中的位置,它可能是您可以读取的地址,也可能不是。 如果不是,则会崩溃。 如果是这样,它将起作用,并且它将读取那里的任何随机内存。 可能是其他变量,空格,代码,从OS分配但尚未使用的内存或其他任何东西。 因此,它是一个伪随机变量(请勿将其用作随机数,否则可能会发生不好的事情)。

更有趣的是,如果您尝试编写它,除了上面的问题之外,您还可能会覆盖随机数据,这可能是其他变量,这些变量将被随机更改,指针现在将指向其他随机存储器,代码现在,它的功能有所不同,或者是堆栈,在这种情况下,您可以跳转到随机内存(实际上,这是某些黑客的工作方式)。

简而言之,不要超出范围。

这是什么原因呢?

正如@Sam所说,您正在做的是“未定义的行为”。 那意味着什么都可能发生。 没事

实际上,将发生的情况是程序将尝试取消引用未定义值的指针。 我们无法预测会是什么。 这可能取决于执行之前发生的情况。 或不。 C ++语言规范什么也没说。 (这是“未定义的行为” ...记住。)

指针将是有效地址,或者是不引用有效存储位置的地址。

  • 如果地址有效,则将获取该单元格中的值。 我们不知道它将是什么,但是它很可能为零……根据上下文,您将看到它为NULL'\\000' 但这可能是另外一回事。

  • 如果地址无效,则尝试访问该地址将产生内存访问错误或分段冲突。 这是由硬件检测到的,该硬件通常用于实现虚拟内存和/或保护系统免受某个进程(应用程序)访问属于OS或另一进程的内存的影响。

这些是典型的现代操作系统中可能发生的行为。 另一方面,如果您的代码在没有内存保护的“裸机”系统上运行,则可以想象,您读取的是一个基本随机的地址可能会落在内存映射的设备寄存器上,并触发设备执行以下操作:做一点事。 一切皆有可能。


这个教训是,当您使用C和C ++进行编码时,需要仔细编写代码,并避免做会导致“未定义行为”的事情。 如果这太难了,请考虑使用一种语言,使编译器和运行时避免您遇到这种麻烦。 (但这是以性能为代价的。)

正如Sam Varshavchik在回答中所说的那样,根据C ++标准,行为是不确定的。

这意味着实现(松散地说,编译器,库和主机系统的组合)可以产生任何喜欢的结果。 并不需要使用两个不同的编译器构建的代码产生相同的结果。 如果将注意力集中在一个编译器上,则不能保证今天和下周三将产生相同的结果。

实际上,访问10元素的数组中的元素100通常会尝试访问内存中相应位置的内容。 在您的示例中,如果int为4字节,则访问a[100]将尝试将数组开始后400字节开始的四个字节视为int

如果该内存存在(可能不存在,因为它可能在操作系统已分配给您的程序的外部内存中),则所获得的结果将取决于驻留在内存中该位置的任何内容。 这可能与程序中的其他变量相对应-由程序中的其他代码将其设置为任意变量。 在运行由操作系统托管的其他程序之后,它可能包含随机的一组位,这些位对应于该内存中存储的内容。 操作系统可能会使用一些随机位覆盖内存,然后再将其提供给程序使用(是的,出于安全原因,某些操作系统会这样做)。 如果该内存位置实际上不存在,则访问它可能会产生某种形式的访问冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM