动态变量与未定义内存之间的C ++差异

时间:2019-02-04 01:39:31

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

我现在正在学习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分配给“新”存储位置?

4 个答案:

答案 0 :(得分:4)

  

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

如果不是由于程序崩溃(如VorpalSword建议),那么也许当您重写(无论您写了什么内存字)时,stdout机制中的某些问题便会中断,这取决于它是否仍保持其原始值。未定义行为的问题在于它是未定义的-也就是说,确切会发生什么将取决于流程中每个可能受影响的机制如何工作的确切细节,更确切地说,当它取决于先决条件时,它将如何失败已被违反。通常,没有人会尝试记录或描述未定义的行为,因为这将是无休止的工作,而且在任何情况下都无济于事,因为无论如何,调用未定义行为的程序都必须修复。

  

即使p1指向随机存储器位置,为什么我也不能更改   它指向的值是什么?

好吧,您可以-但是这样做,您已经调用了未定义的行为,这意味着在此之后不能保证一切正常,如果有任何事情没有做您想要的事情在那之后,唯一要怪的人就是你:)

  

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

因为要使用一块内存,所以要使用一块没有其他代码用于其他用途的内存。否则,您对其所做的任何更改都将覆盖它们在其中放置的任何值(反之亦然),从而导致您的逻辑或它们的逻辑或两者同时发生意外/无用的行为。

'new'运算符使您从堆中分离出一些其他人都无法使用的已知内存,因此您可以确保该内存可用于您自己的私人使用只要。 “删除”运算符将内存返回给堆,以便在使用完之后可以将其重新用于其他目的。

答案 1 :(得分:3)

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

答案 2 :(得分:3)

这里有几件事:

  • 当不初始化变量时,它的值是不确定的(取决于您的编译器,编译器设置,操作系统,当时的计算机状态等)。实际上,这就是当时堆栈上的所有内容。
  • 操作系统需要保证进程隔离-这意味着,如果一个进程行为不当,则不会破坏整个系统或影响其他正在运行的进程。其中之一是内存保护。每个进程都有允许使用的内存。如果随机地址恰好在该区域之外,则您的程序将崩溃。
  • 如果随机地址落在允许的范围内,则可能“无害”,或者您可能破坏进程堆栈,堆或任何其他数量的东西,从而导致后来的神秘崩溃。
  • 最后,它不必指向堆或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 :(得分:1)

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