声明指向整数数组C ++的指针

时间:2012-04-30 02:56:30

标签: c++ arrays pointers

我想在我的类的头文件中声明一个指向整数数组的指针。我有

private:
 int *theName;

然后在构造函数

theName = new int[10];
这会有效吗?还有另一种方法可以做到这一点,所以你有一个指向数组的指针吗?

我认为int * theName创建了一个指向整数而不是整数数组的指针,如果这创建了指向整数数组的指针,那么如何创建一个只指向整数的指针?

同样在析构函数中我可以调用

delete theName; theName = NULL;

是否会删除name整数数组对象,然后将name指向内存中的null?

由于

6 个答案:

答案 0 :(得分:7)

四件事:

  • 一,是的,就是你如何制作一个指向数组的指针。请注意,指向整数的指针和指向整数数组的指针之间没有区别;您可以将整数视为一个元素的数组。如果x[0]是指向整数的指针,您仍然可以使用x,如果*x是指向数组的指针,您仍然可以使用x,它们的工作方式相同

  • 其次,您必须使用delete[] theName delete theName。无论您在何处使用new,都必须使用delete,无论您在何处使用new[],都必须使用delete[]。此外,没有必要设置theName = NULL,因为在运行析构函数后,无论如何都无法再访问theName

  • 第三,编写管理资源的类时,需要编写复制构造函数,移动构造函数,复制赋值运算符和移动赋值运算符。

  • 第四,除非你只是做一个教学练习,否则你应该使用std::vector。它有许多优点,没有实际缺点。如果使用vector,您甚至不必编写其他四个构造函数。

答案 1 :(得分:4)

我毫不犹豫地发帖,但我希望它不会引起问题。

要迂腐:大多数其他答案都是错误的:你创建的是不是指向数组的指针。它是指向int的指针,指向数组的初始元素。

我毫不犹豫地发布了它,原因很简单,这几乎肯定只是在你的问题中使用了错误的措辞 - 指向int的指针几乎肯定是你想要的,它是你真正得到的。

然而,有一些东西作为指向数组的指针。它很少有用,因为当/如果你对它进行指针数学运算(包括下标)时,指向数组的指针的工作方式是它所指向的数组的大小。在您的情况下,您分配10 int s。您可以使用指针下标来引用数组中的int,因此theName[0]引用第一个inttheName[1]引用第二个int等等 - 正是你通常想要的。

如果您正在使用(例如)数组数组,并且想要一个遍历整行的指针,那么可能能够真正使用指向数组的指针一次,ptr[0]是第一行,ptr[1]是第二行,依此类推。例如:

#include <iostream>

static const int x = 20;
static const int y = 10;

int main() {
    char data[y][x];

    auto ptr_array = &data[0];
    char *ptr_char = &data[0][0];

    std::cout << "Address of entire array: " << (void *)data << "\n";

    std::cout << "char *[0] = " << (void *)ptr_char << "\n";
    std::cout << "char *[1] = " << (void *)(ptr_char+1) << "\n";

    std::cout << "array *[0] = " << (void *)ptr_array << "\n";
    std::cout << "array *[1] = " << (void *)(ptr_array+1) << "\n";
    return 0;
}

我已将此更改为使用char(而非int)数组的数组,以使数学更加明显 - sizeof(char) == 1(根据定义)所以算数学更容易一些。当我在我的机器上运行此代码时,我得到的地址是:

Address of entire array: 0047FD2C
char *[0] = 0047FD2C
char *[1] = 0047FD2D
array *[0] = 0047FD2C
array *[1] = 0047FD40

如您所见,ptr[0]以任何方式保存数组的地址。但是,如果指针指向char,则ptr[1]会保留一个更大的地址。然而,指向数组的指针保持地址0x40 - 0x2C = 0x14 = 20更大 - 这符合我们给予数组(20)的X维度。换句话说,我们确实有一个指向数组的指针,并且该指针上的指针算术(或等效地,下标)一次按整个数组工作。

我会重复一遍:至少如果我们忽略了你几乎肯定应该使用std::vector的事实,那么你想要的类型和你得到的类型都是{ {1}}。有pointer to int这样的类型,但几乎可以肯定想要你真正想要的。

答案 2 :(得分:1)

是的,那会有用。

您需要撰写delete[] theName - 如果您使用new TYPE[]进行了分配,则必须使用delete[]运算符进行删除。

theName设置为null是一种很好的形式,虽然在析构函数中是多余的,因为整个对象(以及theName)很快就会停止存在。

更好的C ++方法可能是使用std::vector<int>

答案 3 :(得分:0)

是的,这就是你如何初始化指针。你有一些问题:

  1. 您需要使用delete []为您分配的任何内容致电new[]。您的代码无法正常工作并导致UB。

  2. 您需要实现复制构造函数和赋值运算符。如果将指针复制到您的类型的另一个实例会发生什么?您最终会在其上调用delete []两次。

  3. 术语挑剔:

  4.   

    是否会删除name整数数组对象,然后theName指向内存中的null?

    不,它将theName设置为NULLtheName是一个变量,就像任何其他具有值的变量一样。这个变量恰好是一个地址,因此当这样使用时,是的,它的值将是NULL的数值,无论可能是什么。

答案 4 :(得分:0)

  

还有另一种方法可以做到这一点,所以你有一个指向数组的指针吗?

您可以使用std::vector。这[在大多数情况下]可以在您使用阵列时插入并提供以下好处:

  1. 无需担心内存管理
  2. 需要时自动调整
  3. 可以继续使用array[index]语法
  4. 可以使用.at()方法执行边界检查。
  5. 如果你想要一个指向第一个元素的指针(给C风格的API等)你可以使用:

    std::vector<int> vec(10);
    
    SomeCFunction(&vec[0]);
    

答案 5 :(得分:0)

是的,使用delete []和vector和stuff非常好的答案,但要记住这一点:int * p的类型为“指向int的指针”。它确实是指向单个整数的指针。但是,如果你像这样取消引用p [5],这就像说*(p + 5)一样。这也是数组访问的工作原理。 (以及为什么你可以隐式地将数组转换为指向其第一个元素的指针。)但是,有一个指向数组类型的指针。 int(* p)[10]是“指向大小为10的int数组的指针”。但是,这不是你想要的。因为如果现在你会说p [5]它将意味着*(p + 5)将访问地址p + sizeof * p * 5.但sizeof * p是sizeof int [10],所以你有乱七八糟的东西。 (当然,p [5]的类型是int [10],因为p是指向int [10]的指针; - )