【问题标题】:What happens when you initialize a junk value to something in C?当你在 C 中初始化一个垃圾值时会发生什么?
【发布时间】:2011-02-22 08:38:47
【问题描述】:

假设我们有以下内容:

int main(void) {
   char* ptr;

   printf("%c\n",ptr[24]);  // junk value

   ptr[24] = 'H';

   printf("%c\n", ptr[24]);  // prints H

   return 0;
}

当我将垃圾值更改为其他值时,这是否意味着我正在破坏内存,或者这个值实际上是垃圾,所以我分配给它的新值并不重要?

【问题讨论】:

  • 一个有趣的练习是printf("%p\n", ptr + 24); 并在几个不同的平台上尝试该应用程序。

标签: c memory pointers


【解决方案1】:

您的程序表现出未定义的行为,这意味着:从字面上看,任何事情都可能发生,但仍被标准涵盖为未定义。当我说什么时,我的意思是完全的。它甚至可以让你的电脑变得有知觉并在街上追你。

嗯,通常会发生什么,但这不是保证,是您正在写入未映射的地址空间(在具有分页内存的现代操作系统上)导致分段错误或总线错误(取决于架构、操作系统和运行时实现)。

ptr 是一个未初始化的指针,这意味着指针的值尚未定义。根据定义,未定义的指针指向任何东西和一切,即根本没有有效的对象。使该指针有效的唯一方法是为其分配一个正确的 C 对象的地址,该对象的类型是该指针取消引用的类型。

顺便说一句:Pl​​ain C 有非常非常严格的打字规则。我有时会说它比 C++ 更严格,因为它缺少隐式转换运算符和函数重载。但是它草率的类型转换和糟糕的编译器毁了它在类型安全方面的声誉。

【讨论】:

  • 刚刚发现 BUS Error 是由未对齐的指针引起的。谢谢。 “在街上追你”,我读过的人经常用这个,是布鲁斯·埃克尔吗?
  • 规范表达不是和鼻魔有关吗?
【解决方案2】:

您正在访问调用未定义行为的无效内存位置。任何事情都可能发生,无法预测。

【讨论】:

    【解决方案3】:

    由于大多数 C 实现允许您访问无效的内存位置,因此您实际上是在将 'H' 值分配给该位置。

    但是你不能相信接下来会发生什么。也许您的程序失败了,也许您损坏了其他程序正在使用的内存,或者在多线程环境中,另一个程序可能会覆盖该值。

    【讨论】:

    • C 不允许您访问无效内存。指针的值是未定义的,程序的行为也是如此。 C 标准没有将指针的数值与内存地址相关联——大多数实现都是这样做的,但从技术上讲,只有指针算术规则必须遵守。
    • 对不起,我的意思是因为我假设我的程序之外的任何内存位置都是无效的,指针的值是否未定义。也许答案应该重写为 因为大多数 C 实现都允许....
    • datenwolf 想说的是,“无效内存”严格来说在 C 中不是一个有效的概念,因为它没有出现在标准中。该标准只是说取消引用未初始化的指针是未定义的行为;它并没有说这样做会导致对无效内存的访问(尽管在大多数 C 实现中都会发生这种情况)。
    • @sleske,绝对没有提示未初始化指针指向的内存是否“有效”。在实践中,它通常是您可以访问的内存。例如,也许堆栈上的那个槽以前被指向某个对象的指针占用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2011-03-14
    • 2016-12-12
    • 2023-03-18
    • 2019-12-12
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多