为什么我不能通过将指针传递给函数来初始化数组?

时间:2009-08-11 13:50:27

标签: c++ pointers

我知道这有一个非常简单的解释,但是我已经被一段时间不必使用指针所破坏了。

为什么我不能在c ++中做这样的事情

int* b;
foo(b);

并通过...

初始化数组
void Something::foo(int* a)
{
  a = new int[4];
}

在调用foo(b)之后,b仍为null。这是为什么?

8 个答案:

答案 0 :(得分:13)

指针按值传递给函数。从本质上讲,这意味着复制指针值(但不是指针!)。您修改的只是原始指针的副本。

有两种解决方案,都使用额外的间接层:

  1. 使用引用:

    void f(int*& a) {
        a = new int[4];
    }
    
  2. 或者你传入一个指向指针的指针(在你的情况下不像传统参数那样常规):

    void f(int** pa) {
       *pa = new int[4];
    }
    

    并调用这样的函数:

    f(&a);
    
  3. 就个人而言,我不喜欢两种风格:参数是函数输入,输出应该由返回值处理。到目前为止,我还没有看到在C ++中偏离此规则的令人信服的理由。所以,我的建议是:改用以下代码。

    int* create_array() {
        return new int[4];
    }
    

答案 1 :(得分:6)

您可以通过值将参数传递给foo。改为

foo(int*& a)

答案 2 :(得分:4)

你是值得传递的。

您需要传递参考:

void Something::foo(int* &a)
{
  a = new int[4];
}

这样做可能更清楚:

int* Something::foo()
{
  int* a = new int[4];
  return a;
}

int* b = foo();

确保当您将指针(或更新引用)返回到方法分配的内存时,可以清楚地说明它应该被释放的时间和人员。

答案 3 :(得分:2)

出于同样的原因,你不能通过传递值来初始化整数。

答案 4 :(得分:1)

要点两点:

1)

int* b;

这应该是:

int* b = NULL;

它只是在调试器中报告它是null,因为你在debug下运行。在发布时编译将给b一个随机指针。

2)

如果您将指针传递给指针,那么您的函数应该能够分配内存:

int* b = NULL;
Something::foo(&b);

void Something::foo(int** a)
{
    *a = new int[4];
}

答案 5 :(得分:1)

指针是一个整数值(32位OS是32位整数),它是存储器地址。您将整数值传递给函数。通过将值推送到堆栈来进行传递。然后从堆栈中删除该值,并通过在其上分配一些内存来更改该值。然后退出该函数并删除堆栈帧。删除该堆栈帧中的任何值,包括新分配的内存地址。

你想要做的是传入一个指向指针的指针。

int* b;
foo(&b);

void Something::foo(int** a)
{
  *a = new int[4];
}

在这里你宣布b。它是指向内存位置的整数值。您传入该整数值的地址。即另一个整数值,指向包含指向内存位置的整数值的内存位置。现在在foo函数里面  您将内存分配给指向另一个内存位置的地址。然后当你退出函数时,堆栈展开,指向指针的指针消失。但是,您的原始整数值(即指针)仍保留您刚刚调用new时创建的值。

答案 6 :(得分:0)

您必须使用引用或执行以下操作:

int* b;
foo(b);

void Something::foo(int** a)
{
  *a = new int[4];
}

(这是老派的C方式,我认为参考更好)

答案 7 :(得分:0)

因为您将NULL传递给函数。你需要的是(指针指针):

int* b;
foo(b);

void Something::foo(int** a)
{
  *a = new int[4];
}