分配指向固定大小数组的指针

时间:2011-10-10 23:43:00

标签: c++ pointers multidimensional-array new-operator

我对指针使用的基础知识有两个疑问。

使用以下代码

 int (*p_b)[10];
 p_b = new int[3][10];
 // ..do my stuff
 delete [] p_b

p_b指向一个包含3个元素的数组,每个元素的固定大小为10 int。

Q1:

如果我希望每个元素都是指向固定数组大小的指针,如何声明p_b? 基本上我想要以下

  p_b[0] = pointer to a fixed-array size of 10
  p_b[1] = pointer to a fixed-array size of 10
  // ... and so on

我在考虑int (** p_b)[10],但后来我不知道如何使用new来分配它?我想避免回到更笼统的int** p_b

Q2:

根据我上面的原始代码示例,如何调用new,以便p_b指向除调用p_b = new int[1][10] 之外的10 int的唯一固定大小数组?为了释放记忆,我不得不拨打delete[],而我找不到一个只能呼叫delete的表达式。

6 个答案:

答案 0 :(得分:2)

  

p_b指向一个包含3个元素的数组,每个元素的固定大小为10 int。

     

如果我希望每个元素都是指向固定数组大小的指针,如何声明p_b

你的第一句话是不是完全涵盖了这个问题?

  

根据我上面的原始代码示例,如何调用new,以便p_b指向除调用p_b = new int[1][10]之外的10 int的唯一固定大小数组?要释放内存,我必须调用delete[],而我找不到一个只能删除的表达式。

我完全不明白为什么这是一个问题,但您可以通过将数组包装在另一个类型中来实现...说std::arrayboost::arraystd::vector

答案 1 :(得分:1)

首先,如果您的new表达式带有方括号(new somtype[somesize]),则delete也必须使用方括号(delete [] your_pointer)。

其次,您现在已将p_b定义为指向某些数据的单个指针。如果你真正想要的是一个指针数组,那么你需要将它定义为一个数组。由于您显然需要三个独立的数组,因此您必须分别分配每个数组。如果你从typedef开始,这可能是最简单的:

typedef int *p_int;
p_int p_b[3];

然后你将分配你的三个数组:

for (int i=0; i<3; i++)
    p_b[i] = new int[10];

要删除这些内容,您需要单独删除每个内容:

for (int i=0; i<3; i++)
    delete [] p_b[i];

我绝对同意@Tomalak的说法,你几乎不应该自己搞这样的事情。目前尚不清楚你真正想要实现的目标,但仍然很容易猜到标准容器很可能是一种更简单,更清洁的方式。

答案 2 :(得分:1)

以下是如何实施Q1的示例:

int main()
{
    typedef int foo[10];

    foo* f = new foo[3];

    f[0][5] = 5;
    f[2][7] = 10;

    delete [] f;
}

对于Q2,删除使用new []分配的内存的唯一方法是使用delete []。如果您个人不想编写delete [],则可以使用向量或其他STL容器。真的,除非这是一些硬核超级优化,否则你应该使用矢量。除非你绝对被迫,否则不要手动管理内存。

答案 3 :(得分:0)

要使用原始指针来管理二维数组,必须首先创建一个指向数组元素类型指针的指针,该指针将指向数组的每一行。接下来,必须将每个行指针分配给该行的实际数组元素。

int main()
{
  int **p;

  // declare an array of 3 pointers
  p = new int*[3];

  // declare an array of 10 ints pointed to by each pointer
  for( int i = 0; i < 3; ++i ) {
    p[i] = new int[10];
  }

  // use array as p[i][j]

  // delete each array of ints
  for( int i = 0; i < 3; ++i ) {
    delete[] p[i];
  }

  // delete array of pointers
  delete[] p;
}

更简单的解决方案是使用std::array。如果您的编译器没有提供该类,您也可以使用std::vector

std::array<std::array<int,10>,3> myArr; 
myArr[0][0] = 1;

答案 4 :(得分:0)

对于Q1,我认为你想要

int (*p[3])[10];

如果您不确定,请尝试cdecl

其他答案似乎很好地回答了你的其他问题。

的问候, Yati Sagade

答案 5 :(得分:0)

实际上,没有人发布你的确切问题的答案。

而不是

int (*p_arr)[10] = new int[3][10];
// use, then don't forget to delete[]
delete[] p_arr;

我建议使用

std::vector<std::array<int, 10>> vec_of_arr(3);

或者如果您不需要移动它并且不需要运行时长度:

std::array<std::array<int, 10>, 3> arr_of_arr;

<强> Q1

  

如果我希望每个元素都是指向固定数组大小的指针,如何声明p_b?

int(**pp_arr)[10] = new std::add_pointer_t<int[10]>[3];
for (int i = 0; i < 3; ++i)
    pp_arr[i] = new int[1][10];
// use, then don't forget to delete[]
for (int i = 0; i < 3; ++i)
    delete[] pp_arr[i];
delete[] pp_arr;

该代码的现代变体是

std::vector<std::unique_ptr<std::array<int, 10>>> vec_of_p_arr(3);
for (auto& p_arr : vec_of_p_arr)
    p_arr = std::make_unique<std::array<int, 10>>();

或者如果您不需要移动它并且不需要运行时长度:

std::array<std::unique_ptr<std::array<int, 10>>, 3> arr_of_p_arr;
for (auto& p_arr : arr_of_p_arr)
    p_arr = std::make_unique<std::array<int, 10>>();

<强> Q2

  

根据我上面的原始代码示例,如何调用new,以便p_b指向除调用p_b = new int[1][10]之外的10 int的唯一固定大小数组?

不是没有将数组包装成另一种类型。

std::array<int, 10>* p_arr = new std::array<int, 10>;
// use, then don't forget to delete
delete p_arr;

您可以将std::array<int, 10>替换为您最喜欢的数据包装类型,但不能将其替换为固定大小的数组别名。该代码的现代变体是:

auto p_arr = std::make_unique<std::array<int, 10>>();