首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >堆内存范围

堆内存范围
EN

Stack Overflow用户
提问于 2014-04-23 16:32:50
回答 4查看 627关注 0票数 3

据我所知,堆的性质应该是全球性的,不是吗?因此,我们应该能够在函数中的任何地方访问堆内存。那么为什么下面的代码段错误(分段错误)?

代码语言:javascript
复制
#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;
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-04-23 16:34:30

出现分段错误是因为指针a是通过值传递的,因此调用方看不到在A()中所做的更改,从而导致NULL指针在B()中被取消引用。若要更正,请引用A()传递指针

代码语言:javascript
复制
void A(int*& x)
票数 9
EN

Stack Overflow用户

发布于 2014-04-23 16:43:15

正如其他答案所指出的那样,实际上问题是在A()中分配的内存没有传递给B()

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

当我在您的示例上运行 version 3.4时,它给出了:

代码语言:javascript
复制
$ 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.

在这个特殊的独立示例中,‽多么棒,编译器计算路径的额外时间是可以忽略不计的。在“真正的”代码(不是像这样的合成示例)上,可能会有更多的开销。但对大多数用户来说,这几乎是值得的。

票数 2
EN

Stack Overflow用户

发布于 2014-04-23 16:53:38

问题:据我所知,在本质上应该是全球性的,不是吗?

回答:是。

语句:,因此我们应该能够在函数中的任何地方访问堆内存。

Respons:是的,只要我们知道堆内存值,我们就能够这样做。

问题:,那么为什么下面的代码段错误(分段错误)?

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

  1. 按照Subhajit的建议,将参数类型更改为int*& a
  2. A返回分配的内存地址。 int* A() { int* x=新int10;for(int i= 0;i< 10;i++) { xi = i;}返回x;}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23250284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档