【问题标题】:C++ Differences between Dynamic Variable and Undefined Memory动态变量和未定义内存之间的 C++ 差异
【发布时间】:2019-02-04 01:39:30
【问题描述】:

我现在正在学习 C++ 中动态变量的概念。我遇到的第一个例子如下。

  int *p1 = new int;
  std::cin >> *p1;
  *p = *p + 5;
  std::cout << *p1;

我想知道如果指针 p1 没有指向动态内存位置而是未初始化会发生什么,据我所知,这是未定义的行为。所以,

  int *p1;
  std::cin >> *p1;
  *p1 = *p1 + 7;
  std::cout << *p1;

我试过了,但没有用。它让我从控制台输入一个整数,但没有输出任何东西。这是为什么?即使 p1 指向一个随机内存位置,为什么我不能更改它指向的任何值?为什么我需要将 p 分配给“新”内存位置?

【问题讨论】:

  • 据我了解,当 p1 未初始化时,它可能实际上指向任何地方。但是,当您创建一个动态变量时,它位于堆中,并且行为更可预测。您永远不应该取消引用未初始化的指针。我仍然想看看其他人对此有何看法。
  • 那么,在某些情况下我的第二个代码块会起作用,比如未初始化的变量是否随机指向堆?

标签: c++ pointers dynamic-memory-allocation


【解决方案1】:

它让我从控制台输入一个整数,但没有输出任何东西。 这是为什么呢?

如果不是由于程序崩溃(如 VorpalSword 所建议的那样),那么也许当您重写(无论您重写什么内存字)时,会破坏标准输出机制中的某些东西,而这取决于它保持其原始值。未定义行为的问题在于它是未定义的——也就是说,究竟会发生什么将取决于过程中每个可能受影响的机制如何工作的确切细节,更准确地说,当它依赖于先决条件时它可能会如何失败已被违反。一般来说,没有人会尝试记录或描述未定义的行为,因为这将是一项无休止的工作,而且在任何情况下这样做都没有任何好处,因为无论如何都需要修复调用未定义行为的程序。

即使 p1 指向一个随机内存位置,为什么我不能改变 它所指向的东西的价值?

嗯,你可以——但是这样做,你已经调用了未定义的行为,这意味着在那之后没有任何东西可以保证立即工作,如果有任何东西不能达到你想要的效果在那之后,唯一的责任就是你:)

为什么我需要将 p 分配给“新”内存位置?

因为如果你要使用一块内存,你会想要使用一块没有其他代码用于其他目的的内存。否则,您对其所做的任何更改都将覆盖他们放置在那里的任何值(反之亦然),从而导致您的逻辑或他们的逻辑中出现意外/无用的行为,或两者兼而有之。

'new' 操作符将你从堆中取出一些已知不被任何其他人使用的内存,这样你就可以确保它可供你自己私人使用只要。 'delete' 操作符将该内存返回给堆,以便在您完成后可以将其重新用于其他目的。

【讨论】:

    【解决方案2】:

    这里有几件事:

    • 当您不初始化变量时,未指定其值是多少(取决于您的编译器、编译器设置、您的操作系统、您的机器当时的状态等)。这实际上是当时堆栈中发生的任何事情。
    • 操作系统需要保证进程隔离——这意味着,如果一个进程行为不端,它不会导致整个系统停机,也不会影响其他正在运行的进程。其中之一是内存保护。每个进程都有允许使用的内存。如果随机地址恰好落在该区域之外,您的程序将会崩溃。
    • 如果随机地址落在允许的区域内,那么它可能是“无害的”,或者您可能会破坏您的进程堆栈、堆或任何其他数量的东西,从而导致后来的神秘崩溃。
    • 最后,它不必指向堆或new 一块内存 - 它可以在堆栈上。

    这是一个堆栈示例:

    int x = 0;
    int* p1 = &x;
    std::cin >> *p1;
    *p1 = *p1 + 7;
    std::cout << *p1;
    std::cout << x; // x and *p1 refer to the same value
    

    【讨论】:

      【解决方案3】:

      取消对未初始化指针的引用是undefined behavior,这基本上意味着任何事情都可能发生。通常,实际上会发生以下三件事之一:程序将立即崩溃,或者它将继续工作。它也可能会工作一段时间,但稍后会出现行为不端。但是你不能依赖任何特定的结果——未定义的行为意味着任何事情都可能发生。

      【讨论】:

        【解决方案4】:

        它可能是段错误。您是否尝试过在调试器中单步执行此操作?

        【讨论】:

          猜你喜欢
          • 2015-06-07
          • 2013-06-05
          • 2018-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多