这是C ++(GNU GCC编译器)中指针数组的行为,我无法找到解释,希望有人可以清除这种混淆。
我正在创建一个指针数组(arr_ptr),指针指向有效数据,然后我创建另一个指针数组(arrcopy),我这样做 - 我认为 - 浅层副本(arrcopy = arr_ptr),我得到了预期的数据......到目前为止一直很好。
我不理解的部分是,在删除arr_ptr之后,arrcopy是否应该指向我的有效数据?为什么不发生这种情况? 谢谢。
int main()
{
int a = 1; int b=2; int c=3;
int* ap = &a; int* bp = &b; int* cp = &c;
// Array of pointers
int** arr_ptr = new int*[3];
arr_ptr[0] = ap;
arr_ptr[1] = bp;
arr_ptr[2] = cp;
//shallow copy
int** arrcopy = arr_ptr;
cout << "Values: " << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << "Addresses: " << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
a++;
cout << "After Incrementing a:" << endl;
cout << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
*(arr_ptr[0]) = 5;
cout << "After updating a value to 5:" << endl;
cout << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
//so far so good - works as expected
//deleting arr_ptr
delete[] arr_ptr;
// Why?: shouldn't arrcopy still be pointing to A
cout << "Values: " << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl; //The result I am expecting here is: unknown_value 5
cout << "Addresses: " << arr_ptr[0] << " " << arrcopy[0];
cout << endl;
return 0;
}
答案 0 :(得分:3)
在分配后你没有2个数组,你有2个指向同一个数组的指针:
arr_ptr -------->|ptr0|ptr1|ptr2|ptr3... (allocated memory)
arr_cpy = arr_ptr; // copy only the pointer
现在两个指针指向相同的已分配内存:
arr_ptr -------->|ptr0|ptr1|ptr2|ptr3...
^
arr_cpy -----------|
delete[] arr_ptr; // invalidate the memory that both pointers point to
这给出了:
arr_ptr -------->|xxx0|xxx1|xxx2|xxx3... (invalid memory)
^
arr_cpy -----------|
您调用delete[]
的哪个指针无关紧要,它们都指向同一个已分配内存块,因此在调用之后它们都指向无效内存的同一块
您需要做的是复制整个数组:
int** arr_cpy = new int*[3];
std::copy(arr_ptr, arr_ptr + 3, arr_cpy); // copy the pointers to the new array
或好多了使用std::vector
:
int main()
{
int a = 1; int b=2; int c=3;
int* ap = &a; int* bp = &b; int* cp = &c;
// Array of pointers
std::vector<int*> arr_ptr{3};
arr_ptr[0] = ap;
arr_ptr[1] = bp;
arr_ptr[2] = cp;
//shallow copy
std::vector<int*> arr_cpy = arr_ptr; // copy the whole vector
// ... etc.
不需要delete[]
,当向量超出范围时,内存会自动释放。
答案 1 :(得分:2)
arr_ptr
和arrcopy
都不是数组。两者都只是指针。
C ++指针有点重载。它可以指向单个对象或对象数组。
在您的情况下,使用您在动态内存中分配的数组的地址初始化arr_ptr
。但它也可以用堆栈中单个对象的地址初始化:
int i = 0;
int** arr_ptr = &i;
通过将该指针的值复制到同一类型的另一个指针中,您只需要两个指向相同内存位置的指针:
// array in the heap
[xxxxxxxxxxxxxxxxxxxxxxx]
^
/ \
/ \
/ \
arr_ptr arrcopy