我正在努力学习C.因为我已经熟悉高级语言(PHP,Javascript,Python),我觉得我要做的大部分工作都涉及学习如何替换我认为理所当然的结构(比如变量)通过使用指针和手动管理内存来调整大小的数组.我的问题是我有点担心玩指针.
通常我会尝试使用其他语言功能,但我的问题是指针使用不当可能会产生意外结果.特别是:是否有可能 - 如果我犯了一个错误 - 我可能会破坏其他程序正在使用的内存段,导致这些程序行为不端?或者操作系统(在我的情况下是各种风格的Ubuntu)会阻止我对分配给不同进程的内存进行干预吗?
在前一种情况下,我想有可能(尽管不太可能)我可能会导致其他程序在磁盘上写入错误数据,从而破坏我在硬盘上的一些信息.甚至最差(甚至更不可能,我猜)它可能会损坏某些硬件 - 例如旧的显示器可能被软件烧毁,这会设置超出范围的刷新率.
我知道可能我的担心是不合理的,但是我想知道编译器/操作系统在我管理指针时犯了错误,会阻止我做多少危险的操作.
特别是:是否有可能 - 如果我犯了一个错误 - 我可能会破坏其他程序正在使用的内存段,导致这些程序行为不端?
不是今天可用的大多数(所有?)主要操作系统.内存保护已经成为大多数Unix/Linux系统,Windows和Mac OS的一个功能十年.内存保护是一种操作系统级别的访问控制系统,可以防止程序写入不属于它们的内存.正如您所建议的那样,这既是为了防止软件写入属于其他进程的内存,也是为了防止软件读取不属于它的内存(主要的安全风险).
这并不是说你将来可能不必担心这个问题,但是如果你开始在现代桌面上学习C,那么你就不应该考虑它.如果你的C代码出错了,你可能不会破坏操作系统!:)
这是一个非常有趣的话题,我认为每个人都会从中了解到.当您尝试访问不属于您的内存并且您的进程被系统终止时,您几乎肯定会遇到这种情况.查看这两篇wiki文章以获取更多信息:
http://en.wikipedia.org/wiki/Buffer_overflow和 http://en.wikipedia.org/wiki/Memory_protection
大多数现代的面向桌面的操作系统(包括 Linux)都使用虚拟内存来防止行为不当的程序干扰其他程序。每个进程都有自己的地址空间,如果您溢出缓冲区或类似地误用指针,最糟糕的情况就是进程崩溃。你不应该影响系统中的其他进程,除非你正在编写设备驱动程序或以 root 身份运行(如果你以 root 身份运行,则必须对另一个进程正在读取的文件做一些不好的事情,等等。 ..您仍然无法直接访问另一个进程的内存)。
关于在犯错误之前捕获错误,以下是一些可以帮助您的规则:
malloc、函数参数等)之前,请务必检查它们是否为 null。free,将指针设置为空。这应该可以帮助您捕获一些悬空指针或双重释放错误。(当然,如果您复制了该指针并将其存储在代码中的其他位置,除非您小心,否则您仍然可能会遇到这些问题。)小智 5
腐败和崩溃是可能的,但只要你小心指针所指向的内存中的值的大小,并且你确定你没有交换指针,你确定你不要硬编码存储地址你应该是精细.
除了一些罕见的操作系统之外,您不能影响其他进程.你显然不会损坏任何硬件.(如果可能的话,我的iOS设备很久以前就会被烧毁,因为应用程序商店中的每个应用程序都包含内存故障,因为程序员懒得阅读该死的文档.)
int *i = malloc(sizeof(int));
// Use I further.
free(i);
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
(不确定这是否编译.取决于编译器标志.)
int *i = 0x00ABCDEF; // Hard coded mem adress.
int j = 123;
int *k = &j;
memcpy(i, k, sizeof(int));
Run Code Online (Sandbox Code Playgroud)