我正在学习c ++指针。我写了一些代码看我是否理解正确。
看起来可能有点怪异。我的目的有点复杂。你能告诉我我是否理解正确?还是有我不明白的问题?
#include <iostream>
using namespace std;
int main()
{
int **x = new int*[20];
*x = new int [5]; //x[0] ==>[0,0,0,0,0]
*(x+1) = new int [3]; //x[1] ==>[0,0,0]
*x[0] = 10; //x[0][0] = 10
*(x+1)[0] = 20; //x[1][0] = 20
cout << x[0][0] << endl;
cout << x[1][0] << endl;
delete [] *x;
delete [] *(x+1);
delete [] x;
return 0;
}
答案 0 :(得分:4)
*x[0] = 10;
*(x+1)[0] = 20;
等同于
*(x[0]) = 10;
*((x+1)[0]) = 20;
我不确定你是否是那样的。 IMO,最好使用:
(*x)[0] = 10;
(*(x+1))[0] = 20;
答案 1 :(得分:2)
据我所能确定的那样,您的代码对于注释的期望是正确的,可以防止内存泄漏,并且没有未定义的行为,这一切都很好。
但是,请考虑一秒钟,您必须编写多少不必要的样板代码才能完成此工作。然后使用std::unique_ptr
考虑以下代码,就行为而言,该代码与您的代码完全相同,但是通过使用自动处理该行为的类,删除了负责删除内存的样板:
#include<memory>
int main()
{
auto x = std::make_unique<std::unique_ptr<int[]>[]>(20);
x[0] = std::make_unique<int[]>(5); //x[0] ==>[0,0,0,0,0]
x[1] = std::make_unique<int[]>(3); //x[1] ==>[0,0,0]
*x[0] = 10; //x[0][0] = 10
//This will no longer compile because, while technically correct, this kind of pointer arithmetic
//is inherently unsafe and prone to mistakes
//*(x+1)[0] = 20; //x[1][0] = 20
x[1][0] = 20;
cout << x[0][0] << endl;
cout << x[1][0] << endl;
//No more deletes needed; `std::unique_ptr` manages its own memory and deletes when needed
return 0;
}
现在考虑下一个代码,该代码通过对动态大小的数组std::vector
使用更健壮的惯用法来进一步简化:
#include<vector>
int main()
{
std::vector<std::vector<int>> x(20);
x[0].resize(5); //x[0] ==>[0,0,0,0,0]
x[1].resize(3); //x[1] ==>[0,0,0]
x[0][0] = 10;
x[1][0] = 20;
cout << x[0][0] << endl;
cout << x[1][0] << endl;
return 0;
}
这是一个非常清楚的案例研究,为什么在大多数情况下,您应该偏爱std::unique_ptr<T[]>
或std::vector<T>
之类的东西来描述“ T
的数组”。对于二维数组std::unique_ptr<std::unique_ptr<T[]>[]>
或std::vector<std::vector<T>>
,它们描述的语义与原始代码相同。
答案 2 :(得分:0)
唯一不正确的是,new int []不会初始化其成员。在*x=new int[5]
之后,x可以为{123,456,789,-123,-456}或其他任何值。