C++中的指针和动态分配的数组

Pointers and dynamically allocated arrays in C++

本文关键字:动态分配 数组 指针 C++      更新时间:2023-10-16

我试图在脑海中弄清楚这一点。

int* arrayA = new int[3];
int arrayB[3] = {1,2,3}
arrayA = arrayB;

arrayB的值是否会复制到arrayA?还是arrayA成为arrayB的指针?

new是邪恶的,特别是对于数组。如果需要动态数组,请使用std::vector,如果需要静态数组,请使用std::array1

现在实际的答案很简单。 arrayA是一个指针。所以它指向arrayB.这具有额外的效果:

  1. 您现在泄露了分配的指针。
  2. 尝试delete arrayA现在会崩溃或其他不愉快的事情,因为您将尝试释放未分配的内存。

实际上,虽然C++允许分配结构和类,但它根本不支持分配数组。除非对象的一部分像std::vector一样管理,或者像std::array中那样作为数组成员进行管理(注意:std::array是C++11(。


1 主要原因是容器保证资源将在其析构函数中释放,即所谓的 RAII 习语,避免了大多数内存泄漏和悬而未决的引用机会。

int* arrayA = new int[3];

arrayA 现在将地址存储在内存中,该内存块足够大,可以包含存储在堆上的 3 个整数。

int arrayB[3] = {1,2,3};

arrayB 是一个内存块,它足够大,可以包含存储在堆栈上的 3 个整数。

arrayA = arrayB;

将堆栈上存储的内存块的地址复制到变量 arrayA 中。 您现在丢失了对堆上存储的内存块的唯一引用,并且无法释放内存(内存泄漏(

当当前函数返回时,存储在堆栈上并由 arrayA 指向的内存将无法访问。 特别是返回数组 A(或数组 B(是不安全的。

for

数组 B 的值是否会复制到数组 A?

不。它不会将数组 B 复制到阵列 A。如果你想这样做,你可以这样做,

for (int i=0;i<3;i++) arrayA[i]=arrayB[i]; //This is two arrays has same value

数组 A 会变成指向数组 B 的指针吗?

是的。它成为指向数组 B 数组的指针。在数组 A = 数组 B 之后;语句,在第一行分配的内存无法访问,这是泄漏。

arrayA=arrayB;结果是将 arrayB 的地址复制到 arrayA。arrayA 将开始指向 arrayB。使用检查它,

printf("n Base address of A[%u] base address of B[%u]", arrayA, arrayB);

希望这有帮助。

数组名称表示数组的基址。

数组

A=数组 B;

将阵列 B 的基址存储到阵列 A。可以通过递增指针数组 A 来访问其他值。

*(数组 A( 值为 1

*(数组 A+1( 值为 2

*(数组 A+2( 值为 3

创建的内存应在最后一次使用

删除[] 数组A

Q. Does the value of arrayB get copied over to arrayA? 
Ans. NO

Q. does arrayA become a pointer to arrayB?
Ans YES.

但是您使用 new 分配的内存块会丢失。因为没有人拥有该块的起点地址。

这个程序证明了这一点:

#include<iostream>
using namespace std;
const int MAX=4;
int main(){
   int* arrayA = new int[MAX];
   for(int i=0;i<MAX;i++){  arrayA[i]=i;    }
   int arrayB[MAX] = {10,20,30,40};
   arrayA = arrayB;
   for(int i=0; i<MAX;i++){ cout<<" a["<<i<<"] = "<<arrayA[i]<<endl;    }
   return 0;
}

此代码的输出为:

 a[0] = 10
 a[1] = 20
 a[2] = 30
 a[3] = 40

g++ (Ubuntu 4.8.4-2ubuntu1~14.04( 4.8.4

一般来说也是如此。

这个的可视化有点像这样

arrayA-> [0][1][2][3]
arrayB-> [10][20][30][40]

最初arrayA的地址为[0](+编译器用于取消分配的大小的负索引上的额外内存总和(。


数组 A=数组 B;

数组 A 的地址为 [10];

假设你在数组 A 上调用删除会发生什么?

*** Error in `./a.out': double free or corruption (out): 0x00007fff561281d0 ***

从下面的代码中也可以看出这一点

#include<iostream>
using namespace std;
const int MAX=4;
int main(){
    int* arrayA = new int[MAX*2];
    for(int i=0;i<MAX;i++){ arrayA[i]=i;    }
    int* arrayC = new int[MAX];
    int j=0;
    for(int i=MAX*100;i>=0;i-=10,j++){  arrayC[j]=i;    }
    arrayA = arrayC;
    for(int i=0; i<MAX;i++){    cout<<" a["<<i<<"] = "<<arrayA[i]<<endl;    }
    delete[] arrayA;
return 0;
}

输出是:

 a[0] = 400
 a[1] = 390
 a[2] = 380
 a[3] = 370
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000002028040 ***
Aborted (core dumped)

只需注意:

"下一个大小无效">

这清楚地说明了在负索引中 arrayA 之前写入的大小值。