【问题标题】:Scope of Heap Memory堆内存的范围
【发布时间】:2014-06-08 15:20:56
【问题描述】:

据我所知,堆本质上应该是全局的,不是吗?所以我们应该能够在函数中任何我们想要的地方访问堆内存。那为什么下面的代码会出现段错误(Segmentation Fault)?

#include <stdio.h>
using namespace std;

void A(int* x)
{
  x = new int[10];
  for(int i = 0; i< 10; i++)
  {
    x[i] = i;
  }
}

void B(int *x)
{
  printf("%d", x[8]);
}

int main()
{
  int* a = NULL;
  A(a);
  B(a);
  return 0;
}

【问题讨论】:

  • Ainput 参数应该如何影响B

标签: c++ pointers memory memory-management


【解决方案1】:

发生分段错误是因为指针 a 正在按值传递,因此在 A() 中所做的更改对调用者不可见,从而导致 NULL 指针在 B() 中被取消引用。要更正,请通过引用 A() 传递指针:

void A(int*& x)

【讨论】:

    【解决方案2】:

    A(a) 和 B(a) 的调用都是 By Value 对于 a。因此,A() 或 B() 内部的任何更改都不会受到调用者的影响。

    请致电,

    void A(int*& a);
    

    【讨论】:

      【解决方案3】:

      正如其他答案所示,确实问题在于A() 中分配的内存没有传递给B()

      但值得注意的是,您可以使用免费提供的工具使用静态分析来检测此问题。

      当我在您的示例中运行 clang++ version 3.4 时,它给出:

      $ make
      clang++ -Wall -Wextra --analyze   -c -o go.o go.cpp
      go.cpp:16:16: warning: Array access (from variable 'x') results in a null pointer dereference
        printf("%d", x[8]);
                     ^~~~
      1 warning generated.
      

      这太棒了‽在这个特定的独立示例中,编译器评估路径的额外时间可以忽略不计。 “真实”代码(不是像这样的合成示例)可能会产生更多开销。但对于大多数用户来说,这几乎肯定是值得的。

      【讨论】:

        【解决方案4】:

        问题:据我所知,堆本质上应该是全局的,不是吗?

        回答:是的。

        声明:因此我们应该能够在函数中的任何位置访问堆内存。

        回应:是的,只要我们知道堆内存值,我们就能做到。

        问题:那么为什么会出现以下代码段错误(Segmentation Fault)?

        答案:在一个函数中分配堆内存并不能保证该内存值对其他函数可见。 operator new 返回的地址必须以某种方式提供给其他函数。您可以通过以下几种方式做到这一点:

        1. 按照 Subhajit 的建议,将参数类型更改为 int*&amp; a

        2. A返回分配的内存地址。

          int* A()
          {
            int* x = new int[10];
            for(int i = 0; i< 10; i++)
            {
              x[i] = i;
            }
            return x;
          }
          

        【讨论】:

          猜你喜欢
          • 2018-01-10
          • 2021-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-30
          • 2018-04-21
          • 1970-01-01
          • 2021-09-17
          相关资源
          最近更新 更多