我创建了一个测试类(tc),它包含一个指向int的数组指针。
class TC
{
public:
int **values;
TC(){values = new int*[10];
};
当我实例化实例并进行以下更改时:
TC *a = new TC();
int **values = &*a->values;
int **oldvalues = values;
values = new int*[10];
values[0] = oldvalues[0];
...
values[9] = oldvalues[9];
delete [] oldvalues;
for(int i = 0; i < 10; i++){
delete values[i];
}
delete [] values;
现在有趣的是:
values = new int*[10];
*a->values = *values;
values[0] = new int(1);
values[9] = new int(10);
std::cout << *values[0] << " " << *values[9];
打印出来
1 10
但切换两行
values = new int*[10];
*a->values = *values;
到
*a->values = *new int*[10];
values = &*a->values;
打印
182939382 10
第一部分是指针。
有人可以解释为什么会这样吗?两种处理指针的方法有什么区别?
编辑: 我很欣赏建设性的意见。您可能会告诉我没有任何c ++和指针处理经验。所以请帮助我理解我所犯的错误。
答案 0 :(得分:4)
此
*a->values = *values;
与
相同 a->values[0] = values[0];
但是values[0]
未初始化,所以你不想从中读取。
答案 1 :(得分:1)
如果这很长,您可以跳到底部的 tldr 部分,但这不会帮助您理解问题,因此您需要阅读其余部分。
我的生锈,但有一些非常奇怪的部分:
让我们从这开始:
TC *a = new TC();
int **values = &*a->values;
int **oldvalues = values;
values = new int*[10];
values[0] = oldvalues[0];
...
values[9] = oldvalues[9];
delete [] oldvalues;
for(int i = 0; i < 10; i++){
delete values[i];
}
delete [] values;
TC *a = new TC();
非常好
int **values = &*a->values;
让我们一步一步地看看下半部&*a->values;
a //pointer to tc
a->values //access values member of the tc a points to
//this is a int**
*a->values //dereference the int**, so we have a int*
&*a->values; //get the address of int*, so we have int** again
总之,正如评论中所述,你可以写a->values.
让我们看一下,你似乎使用int **来保存指向int指针数组的指针。
现在int **values = a->values;
归结为什么?你复制一个指针,这意味着**values
和a->values
现在引用相同的地址(稍微关闭,但现在考虑将Arrays作为指向第一个元素的指针,必须使用索引运算符[]
,否则它们引用第一个元素)。这意味着您指向两次相同的数组
值 \ | - 由TC()创建的数组{values = new int * [10]; / a-&gt; values /
int **oldvalues = values;
基本上你创建了一个指向同一个数组的第三个指针,原因是什么?
values = new int*[10];
在您将 values
初始化为a->values
之前从 values[0] = oldvalues[0];
...
values[9] = oldvalues[9];
读取一次之前覆盖 delete [] oldvalues;
。
oldvalues
注意到你有两个指针,你现在复制数据。复制内存块的循环或函数可以简化这一点,但我建议使用stl类,从stl中查看vector。
TC
删除TC
,删除destructor
- 类使用的数组。
虽然需要删除使用new创建的内容,但如果delete
的{{1}}尝试删除数组(尽管不应多次调用values
),这可能会很糟糕。同一个对象)。此外,由于您的班级似乎认为for(int i = 0; i < 10; i++){
delete values[i];
}
delete [] values;
是有效的,为什么不覆盖数组中的值?
*arrayOfPointers[3]
你记得在删除数组之前删除所有整数,这很好,但为什么不覆盖它们呢?此外,如果你写一个(你应该),这也应该由析构函数处理。对于可疑的东西,为什么要复制元素,只是为了删除它们?
此外,为什么不使用整数数组呢?是一个真正需要的整数指针数组吗?
这将是一个int数组[1,2,3,7]。 虽然这是一个指针数组:[见1,见2,见4,见5],此外你在以下内存地址中有以下数字1 @ 1,2 @ 2,3 @ 4,7 @ < / p>
对于指针数组,您必须执行以下操作才能获得数字:
4th
执行以下操作:
see 5
的值(用于索引开始计数为0)数组元素,7
已加载aarrayOfIntegers[3]
对于整数数组values = new int*[10];
就足够了,可以节省一个间接级别。
到最后一个片段:
*a->values = *values;
您创建一个数组来替换刚刚删除的数组。
a->values = new int*[10];
指定第一个元素,请参阅Ben Voigts answer并记住数组只是指向第一个元素的指针。你取消引用它就可以复制第一个数组元素。您可以将这两行放在一起,并通过放置:
来消除错误values[0] = new int(1);
values[9] = new int(10);
std::cout << *values[0] << " " << *values[9];
返回您的代码:
TC *a = new TC();
a->values[0] = 1;
a->values[9] =10:
std::cout << a->values[0] << " " << a->values[9];
你经历了所有这些麻烦,只是改变了第一个和最后一个号码......
TLDR,更短的解决方案
让我告诉你如何以更短的方式完成:
类TC { 上市: int *值; TC():values(new int [10]){} // google初始化列表 ~TC(){删除值; } //析构函数,在需要清理实例时调用 };
用法:
TC a();
a.values[0] = 1;
a.values[9] =10:
std::cout << a.values[0] << " " << a.values[9];
或没有指针
{{1}}