指针的危险

时间:2011-01-16 13:17:55

标签: c pointers

我正在努力学习C.因为我已经熟悉高级语言(PHP,Javascript,Python),我觉得我必须做的大部分工作都涉及学习如何替换我认为理所当然的结构(比如可变大小的数组)通过使用指针,并手动管理内存。我的问题是我有点担心玩指针。

通常我会尝试使用其他语言功能,但我的问题是指针使用不当可能会产生意外结果。特别是:是否有可能 - 如果我犯了一个错误 - 我可能会破坏其他程序正在使用的内存段,导致这些程序行为不端?或者操作系统(在我的情况下是各种风格的Ubuntu)是否会阻止我对分配给不同进程的内存进行干扰?

在前一种情况下,我想有可能(尽管不太可能)我可能会让其他程序在磁盘上写入错误数据,破坏我在硬盘上的一些信息。甚至最差(甚至更不可能,我猜)它可能会损坏某些硬件 - 例如旧的显示器可能被软件烧毁,这将设置超出范围的刷新率。

我知道可能我的担心是不合理的,但我想知道编译器/操作系统在管理指针时会错误地进行危险操作的程度。

4 个答案:

答案 0 :(得分:7)

  

特别是:是否有可能 - 如果我犯了错误 - 我可能会破坏其他程序正在使用的内存段,从而导致这些程序行为不端?

目前不适用于大多数(所有?)主要操作系统。内存保护已经成为大多数Unix / Linux系统,Windows和Mac OS的一个功能十年。内存保护是一种操作系统级别的访问控制系统,可以防止程序写入不属于它们的内存。正如您所建议的那样,这既可以防止软件写入属于其他进程的内存,也可以防止软件读取不属于它的内存(主要的安全风险)。 / p>

这并不是说你将来可能不必担心,但如果你开始在现代桌面上学习C,那么你就不应该考虑这个问题。如果你的C代码出错了,你可能不会破坏操作系统! :)

这是一个非常有趣的话题,我认为每个人都会从中了解到。当您尝试访问不属于您的内存并且您的进程被系统终止时,您几乎肯定会遇到这种情况。查看这两篇wiki文章以获取更多信息:

http://en.wikipedia.org/wiki/Buffer_overflowhttp://en.wikipedia.org/wiki/Memory_protection

答案 1 :(得分:5)

腐败和崩溃是可能的,但只要你小心指针所指向的内存中的值大小,你确定你没有交换指针,你确定你不要HARDCODE MEMORY ADDRESSES 你应该没问题。

除了一些罕见的操作系统外,您不能影响其他进程。你显然不会损坏任何硬件。 (如果可能的话,我的iOS设备很久以前就会被烧毁,因为应用程序商店中的每个应用程序都包含内存故障,因为程序员懒得阅读该死的文档。 )功能

好例子

int *i = malloc(sizeof(int));
// Use I further.
free(i);

错误的例子

int *i;
i = malloc(sizeof(int));
double j;
i = &j;
j = 3.1415// Mem corruption due to differently sized values, given a double is LARGER than an int.

(不确定是否编译。取决于编译器标志。)

可怕的例子,99%保证腐败

int *i = 0x00ABCDEF; // Hard coded mem adress.
int j = 123;
int *k = &j;
memcpy(i, k, sizeof(int));

答案 2 :(得分:3)

大多数现代的,面向桌面的操作系统(包括Linux)都使用虚拟内存来防止行为不端的程序破坏其他程序。每个进程都有自己的地址空间,如果你溢出缓冲区或类似地滥用指针,那么可能发生的最坏情况就是你的进程崩溃了。您不应该影响系统中的其他进程,除非您正在编写设备驱动程序或以root身份运行(如果您以root身份运行,则必须对另一个进程正在读取的文件执行某些不好的操作等。 ..你仍然无法直接访问另一个进程的内存。)

在您制作错误之前捕获错误,以下是一些可以帮助您的规则:

  1. 在使用之前,请始终检查任何新接收的指针(例如malloc的返回值,函数参数等)是否为null。
  2. 将编译器的警告一直提升并注意它们。
  3. free动态分配的内存之后,将指针设置为null。这应该可以帮助您捕获一些悬空指针或双重自由错误。 (当然,如果您复制了指针并将其存储在代码中的其他位置,除非您小心,否则仍可能存在这些问题。)

答案 3 :(得分:2)

在大多数现代操作系统(包括Linux)中,每个进程都在一个单独的地址空间中运行,这意味着它可以处理的所有内存都不是真正的RAM,而是它自己的私有“内存沙箱” “,这不会影响其他应用程序(实际上,如果您可以与其他应用程序共享RW内存段,但您和其他应用程序必须明确创建它们。)

顺便说一下,通常如果你用指针做错误,你会得到指向无效内存位置的指针,并且第一次尝试取消引用它们时,操作系统将关闭你的应用程序并出现分段错误;不要担心它,它只是操作系统告诉你你搞乱指针。 :)另一方面,最严重的问题是操作系统无法检测到你的指针错误。