当我将一个数组赋值给另一个数组时,实际被复制的是什么



我试图理解当我将一个数组指针的值赋给另一个数组指针时,在c++中会发生什么。假设我有:

int *a = new int[10];
int *b = new int[10];
for (int i =0; i< 10; i++) {
    a[i] = i;
}
b=a; 

当我打印出b的值时,我得到与a相同的值。是有意义的。但什么是实际得到保存在b指针?是数组a的内存地址吗?我试着打印出&a&b,但我得到两个不同的值。那么b是如何获得a的所有值的呢?

另外,如果它们是单独存储的,我是否应该在传输后删除a ?delete [] a

谢谢,我对c++很陌生,任何帮助都会很棒。

首先,你不能将一个数组赋值给另一个数组,而是将一个指针传递给另一个指针。如果这样还不能让你更容易理解发生了什么,那就继续往下读……

当你这样做

int *a = new int[10];
int *b = new int[10];

你会得到这样的内容:

<>之前+---+ +------------------------+| a | --> |为a |分配的内存+---+ +------------------------++---+ +------------------------+| b | --> |为b分配的内存|+---+ +------------------------+之前

赋值后

b = a;

它看起来像这样

<>之前+---+ +------------------------+| a | -+-> |为a |分配的内存+---+ | +------------------------+|+---+ | +------------------------+| b | -/|为b |分配的内存+---+ +------------------------+之前

换句话说,b指向与a相同的内存,没有指向最初为b分配的内存,因此它是不可访问的,并且您将出现内存泄漏

更进一步,试着做

delete[] a;
delete[] b;
当您尝试两次释放相同的内存时,

将导致未定义行为

你只是给数组分配一个指针。因此b将指向与a相同的地址。

你得到2个不同的地址,因为你打印的是指针本身的地址,而不是存储在指针中的地址。

&a != &b  //the addresses of the pointer variables are different
a == b  // the address stored in the pointers is the same

但是实际上在b指针中保存了什么?是因为记忆吗?数组a的地址

存储在a指针中的内存地址。

另外,如果它们是分开存储的,我是否应该删除after转移?删除[]a

如果删除a指向的内存,b将指向一个已分配的内存区域。

由于b是一个int型指针,给它赋值将只赋值int型的内存地址。从本质上讲,数组的核心不过是指针算术,它们的工作原理是根据元素字节大小移动到下一个内存地址,移动特定字节数。因此,当涉及到数组时,您将拥有指针或指向指针的指针,这些指针最终指向int或其他数据类型(如char)。然后,为了移动到数组的下一个元素,只需将sizeof(int)添加到指针地址,即可获得数组的下一个元素。但是使用指针算术,因为C/c++已经知道指针所指向的数据类型的字节结构。在指针上下文中使用++--表示向前或向后移动到数组的下一个元素。

当你赋值b = a时,因为它们都是指向int型的指针,你只是将a中初始分配内存的第一个元素的地址赋值给b。这样就失去了对分配的第二个10 int内存的引用。由于您丢失了对已分配内存的引用,这将导致内存泄漏,因为没有对delete的引用。

当您想用c++编程时,您必须使用c++方式。所以使用STL容器。最简单实用的容器是vector:

#include <vector>
std::vector<int> a(10);
std::vector<int> b(10);
for (int i =0; i< a.size(); i++) {
   a[i] = i;
}
b=a; //it works!!!
assert(a==b);

不需要对vector使用任何delete操作符

首先,通过执行b=a,您有内存泄漏。你正在复制数组a的第一个值的地址(假设&(a[0]) == a)到变量b,结果你完全失去了对数组b的第一个值的地址的控制。在做这样的操作之前,你应该总是先调用delete运算符。

要记住,指针变量总是存储一个地址,但因为它也是一个变量,它也有自己的地址。因此,在变量/指针中存储了数组a的第一个值的地址,所以如果你打印a,你就得到了那个地址。如果你输出&a,你会得到变量/指针a的地址,这在这个例子中对你来说是没有用的。

为了更好地理解,想象一个数组是存储在内存中的连续变量的一个分支,你总是通过只知道这些连续变量的第一个值的地址来访问它们。所以,当你说a[0]时,它就像说"给我数组的第一个变量的值的内容",然后当你说a[1]时,它就像要求位于a[0]地址的变量的值加上a[0]旁边存储在内存中的下一个变量,即变量a[1],也等于*(a+1)。(是的,*(a+1)等于a[1],等等)

同样,试着读一点关于指针间操作的知识。例如,和addressA + 1等于存储在内存中的下一个地址(从地址A开始)。

最后但并非最不重要的是,为了更好地了解这些人员,打印指针的值和地址并使用它们(解决一些简单的数组和指针练习)。

最新更新