c - C中未初始化的指针到底有什么危险

标签 c pointers initialization

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

Trevor 所说的“分配 f 的空间时堆栈中的内容”是什么意思?默认情况下,“未初始化”指针是否初始化为内存中的随机位置?或者他们的“随机”行为是否与分配给这些指针的内存有关,因为堆栈上的意外行为被奇怪的值(然后被引用)填充。

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

最佳答案

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



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

这只是典型的行为。从理论的角度来看,使用不确定的值是未定义的行为。可能会发生比简单地访问无效地址或有效地址更奇怪的事情(使用 accidentallypurposely 使用未初始化数据(不是地址)的示例)。

以下是 Cyclone 等受限制的 C 子集旨在防止的危险类型:
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 , 并且它是未定义的行为。

关于c - C中未初始化的指针到底有什么危险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13347880/

相关文章:

c - 为什么 SDL2 枚举具有很高的意外值?

c++ - LoadInst 和 StoreInst 值和地址 LLVM

c++ - 实例化派生类的类的复制构造函数

c - 如何使用指针?在C中

c - 指向位数组的指针数组

带有静态初始值设定项的java嵌套类

pointers - 如何在 Go 中初始化一个指向结构的指针类型?

java - C + JNI 无法执行一个非常简单的程序

python - 属性应该进行重要的初始化吗?

c - 如何从汇编代码运行 C 二进制文件?