C中未初始化的指针的危险到底是什么 [英] what exactly is the danger of an uninitialized pointer in C

查看:124
本文介绍了C中未初始化的指针的危险到底是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过Jim Trevor的"旋风:PL类的C 的安全方言.特雷弗(Trevor)和他的合著者正在尝试制作一个安全的C版本,因此他们消除了其语言中未初始化的指针. 在未初始化的指针上仔细搜索,似乎未初始化的指针指向内存中的随机位置.似乎仅此一项就使它们不安全.如果引用未初始化的指针,则会跳转到内存的不安全部分.时期.但是Trevor谈论它们的方式似乎暗示它更为复杂.他引用了以下代码,并解释说,当函数FrmGetObjectIndex取消引用f时,它不会访问有效的指针,而是访问不可预测的地址-分配f的空间时堆栈上的内容.

I am trying get a handle on C as I work my way thru Jim Trevor's "Cyclone: A safe dialect of C" for a PL class. Trevor and his co-authors are trying to make a safe version of C, so they eliminate uninitialized pointers in their language. Googling around a bit on uninitialized pointers, it seems like un-initialized pointers point to random locations in memory. It seems like this alone makes them unsafe. If you reference an un-itilialized pointer, you jump to an unsafe part of memory. Period. But the way Trevor talks about them seems to imply that it is more complex. He cites the following code, and explains that when the function FrmGetObjectIndex dereferences f, it isn’t accessing a valid pointer, but rather an unpredictable address — whatever was on the stack when the space for f was allocated.

Trevor的含义是分配f的空间时堆栈中的所有内容"?默认情况下,未初始化"的指针是否初始化为内存中的随机位置?还是由于堆栈上的意外行为,它们的随机"行为与分配给这些指针的内存充满了奇怪的值(然后被引用)有关?

What does Trevor mean by "whatever was on the stack when the space for f was allocated"? Are "un-initialized" pointers initialized to random locations in memory by default? Or does their "random" behavior have to do with the memory allocated for these pointers getting filled with strange values (that are then referenced) because of unexpected behavior on the stack.

Form *f;
   switch (event->eType) {
   case frmOpenEvent:
   f = FrmGetActiveForm(); ...
   case ctlSelectEvent:
   i = FrmGetObjectIndex(f, field); ...
}

推荐答案

Trevor的含义是分配f的空间时栈中的所有空间"是什么?

What does Trevor mean by "whatever was on the stack when the space for f was allocated"?

他的意思是,在大多数汇编语言中,单独的指令用于在堆栈上保留空间并在新保留的空间内写入初始值.如果C程序使用未初始化的变量,则该程序通常会在运行时通常执行保留堆栈空间但没有设置堆栈空间的指令.使用指针时,它实际上将包含保留空间之前在堆栈上的位模式.在好的情况下,这将是一个无效的地址.在最坏的情况下,这恰好是一个有效的地址,其后果将是不可预测的.

He means that in most assembly languages, separate instructions are used to reserve space on the stack and to write an initial value inside the newly reserved space. If a C program uses an uninitialized variable, the program will typically at run-time execute the instruction that reserves stack space but no instruction that sets it. When the pointer is used, it will literally contain the bit pattern that was on the stack before space was reserved. In the good cases this will be an invalid address. In the bad cases this will happen to be a valid address, and the effects will be unpredictable.

这只是典型行为.从理论上讲,使用不确定值是未定义行为.除了简单地访问无效地址或有效地址之外,还会发生很多奇怪的事情(例如,使用未初始化数据(而非地址)的示例故意).

This is only a typical behavior. From the theoretical point of view, using an indeterminate value is undefined behavior. Much stranger things than simply accessing an invalid address or a valid one can happen (examples with uninitialized data (not addresses) used accidentally or purposely).

以下是C的受限子集(如Cyclone)旨在防止的危险:

Here is the sort of dangers that a restricted subset of C such as Cyclone aims to prevent:

int a, *p;

int main(int c, char **v){
  int l, *lp, i;
  if (c & 1) 
    a = l + 1;      // danger
  if (c & 2)
    *lp = 3;        // danger
  if (c & 4)
    {
      p = &a;  
      for (i=0; i<=1; i++)
        {
          int block_local;
          *p = 4;   // danger
          p = &block_local;
        }
    }
}

在最后的危险行中,实际上,很可能会将4写入变量block_local,但实际上,在第二次迭代中,p是不确定的,程序不应访问*p,并且它是未定义的行为.

In the last dangerous line, in practice, it is most likely that 4 will be written to variable block_local, but in reality, at the second iteration, p is indeterminate, the program is not supposed to access *p, and it is undefined behavior when it does.

这篇关于C中未初始化的指针的危险到底是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆