2

我对 C++ 有点陌生。我习惯用 Java 编程。这个特殊的问题给我带来了很大的问题,因为 C++ 在处理数组时不像 Java。在 C++ 中,数组只是指针。

但是为什么这段代码:

#include <iostream>
#define SIZE 3
using namespace std;

void printArray(int*, int);
int * getArray();
int ctr = 0;

int main() {
  int * array = getArray();

  cout << endl << "Verifying 2" << endl;
  for (ctr = 0; ctr < SIZE; ctr++)
    cout << array[ctr] << endl;

  printArray(array, SIZE);
  return 0;
}

int * getArray() {
  int a[] = {1, 2, 3};
  cout << endl << "Verifying 1" << endl;
  for (ctr = 0; ctr < SIZE; ctr++)
    cout << a[ctr] << endl;
  return a;
}

void printArray(int array[], int sizer) {
  cout << endl << "Verifying 3" << endl;
  int ctr = 0;
  for (ctr = 0; ctr < sizer; ctr++) {
    cout << array[ctr] << endl;
  }
}

打印出验证 2 和验证 3 的任意值。也许这与数组真正作为指针处理的方式有关。

4

3 回答 3

9

问题是您不能返回本地数组:

int a[] = {1, 2, 3};
...
return a;

是无效的。您需要a在返回之前复制到动态内存中。目前,由于是在自动a存储中分配的,因此一旦函数返回,数组的内存就会被回收,从而使返回的值无效。Java 没有同样的问题,因为包括数组在内的所有对象都是在动态存储中分配的。

更好的是,您应该避免使用数组来支持旨在替换它们的 C++ 类。在这种情况下,使用 astd::vector<int>将是更好的选择。

于 2012-10-05T02:42:48.653 回答
6

因为您的数组是堆栈分配的。从 Java 迁移到 C++,您必须非常小心对象的生命周期。在 Java 中,所有内容都是堆分配的,并且在没有对它的引用时进行垃圾收集。

然而,在这里,您定义了一个堆栈分配的数组 a,当您退出函数 getArray 时该数组被销毁。这是向量优于普通数组的(许多)原​​因之一——它们为您处理分配和释放。

#include <vector>

std::vector<int> getArray() 
{
    std::vector<int> a = {1, 2, 3};
    return a;
}
于 2012-10-05T02:48:59.293 回答
1

内存中有两个地方可以存放变量:栈和堆。堆栈包含在方法中创建的局部变量。堆在其他条件下保存其他变量,例如静态变量。

当您在其中创建a时,GetArray()这是一个存储在堆栈中的局部变量,并且a是指向该位置的指针。当方法返回指针时,堆栈的该层被释放(包括指针指向的实际值)。

相反,您需要动态分配数组,然后值将在函数返回时不会清除的堆中,a并将指向它们那里。

int * GetArray() {
  int* a = new int[3];
  a[0] = 1;
  a[1] = 2;
  a[2] = 3;
  cout << endl << "Verifying 1" << endl;
  for (int ctr = 0; ctr < 3; ctr++)
    cout << a[ctr] << endl;
  return a;
}

现在,您在函数之间传递这些整数的地址,而值都位于堆中,直到程序结束或(最好)delete它们才被释放。

于 2012-10-05T02:55:28.200 回答