c++中指针数组的处理和删除
Handling of arrays of pointers in c++ and deleting them
我创建了一个测试类(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];
打印出
101
但是两行互换
values = new int*[10];
*a->values = *values;
*a->values = *new int*[10];
values = &*a->values;
打印
182939382 10
第一部分是某个指针。
谁能解释一下为什么会这样?处理指针的两种方式有什么不同?
编辑:我希望能有建设性的意见。你可能会说我没有任何c++和指针处理的经验。所以请帮助我了解我所犯的错误。
This
*a->values = *values;
与
相同 a->values[0] = values[0];
但是values[0]
是未初始化的,所以你不想从它读取
如果你觉得这太长了,你可以跳到底部的tldr部分,但这并不能帮助你理解问题,因此你需要阅读剩下的内容。
我的c是生锈的,但有一些非常奇怪的部分:
让我们从这个开始:
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
现在指向相同的地址(稍微偏离,但现在将数组视为指向第一个元素的指针,必须使用索引操作符[]
延迟,否则它们指向第一个元素)。这意味着你两次指向同一个数组
值|- TC()创建的数组{values = new int*[10];/值->/
int **oldvalues = values;
基本上你创建了指向同一个数组的第三个指针,出于什么原因?
values = new int*[10];
这里,在初始化为a->values
时,覆盖了 values
,然后从它读取一次。
values[0] = oldvalues[0];
...
values[9] = oldvalues[9];
注意到你有两个指针,你现在复制数据。循环或函数复制内存块可以缓解这个问题,但我建议使用stl类,从stl.
中查看vector。delete [] oldvalues;
删除oldvalues
,即删除TC
-Class使用的数组。虽然需要删除用new创建的对象,但如果TC
的destructor
也试图删除数组(尽管不会为同一个对象多次调用delete
),这可能会很糟糕。此外,因为你的类似乎假设values
总是有效的,为什么不覆盖数组中的值?
for(int i = 0; i < 10; i++){
delete values[i];
}
delete [] values;
你记得在删除数组之前删除所有整数,这很好,但为什么不覆盖它们呢?此外,这也应该由析构函数处理,如果你写了一个的话(你应该)。但值得怀疑的是,为什么要复制这些元素,只是为了删除它们?
此外,为什么不使用整数数组呢?指向整数的指针数组真的有必要吗?
这将是一个int数组[1,2,3,7]。虽然这是一个指针数组:[参见1,参见2,参见4,参见5],但除此之外,在以下内存地址中有以下数字1@1,2@2,3@4,7@5
对于指针数组,您必须执行以下操作才能获得数字:
*arrayOfPointers[3]
执行以下操作:
-
4th
(索引从0开始计数)数组元素的值,see 5
被加载 - 该值被解引用,这意味着计算机查找标签为5的内存位置并看到
7
对于一个整数数组,aarrayOfIntegers[3]
是足够的,节省了一级间接。
到最后一个代码段:
values = new int*[10];
创建一个数组来替换刚才删除的数组。
*a->values = *values;
赋值第一个元素,参考Ben Voigts的回答,记住数组只是指向第一个元素的指针。因为你对它解引用,你复制了第一个数组元素。您可以将这两行合并为一行,并通过添加
来消除错误:a->values = new int*[10];
回到你的代码:
values[0] = new int(1);
values[9] = new int(10);
std::cout << *values[0] << " " << *values[9];
你经历了这么多麻烦只是为了改变第一个和最后一个数字....
TLDR,短溶液
让我告诉你如何用更短的方法来完成它:
类TC{公众:int *值;TC(): values(new int[10]) {}//google初始化列表~TC(){删除值;}//析构函数,在需要清理实例时调用
};用法:
TC *a = new TC();
a->values[0] = 1;
a->values[9] =10:
std::cout << a->values[0] << " " << a->values[9];
或不带指针
TC a();
a.values[0] = 1;
a.values[9] =10:
std::cout << a.values[0] << " " << a.values[9];
- 如果我想链接静态库并删除未使用的符号.txt我应该如何处理 Cmakelist
- 处理从列表中删除指向对象的指针的"healthy"方法是什么?
- 从之前添加的批处理文件中删除单词
- 使用 GCC 对 C 文件进行部分预处理(不删除 "define" 指令)
- 从向量中删除元素时未处理的异常
- 智能指针自定义删除器中的处理条件
- 删除节点并处理新的 nullptr 和链接节点
- 如何在 C++ 中的文件处理中删除文件
- 有什么方法可以通过删除表达式安全地处理两次释放内存?
- c++是否需要在用户定义和类特定的删除运算符中处理nullptr
- 重命名批处理文件(删除名称中的一些符号)(python/matlab/shell)
- 预处理一个自定义文本文件,以使用Boost Spirit删除注释
- 类的静态实例无法在程序退出时正确处理资源删除
- 如果未分配申报表,是否需要删除或处理动态数组?还是它被函数删除
- 从注册表中删除项和子项:代码引发未经处理的异常
- 由于删除(试图处理异常..)而崩溃
- C++映射的指针在退出时自动释放,如何处理删除
- 如何在删除或处理文件夹树时处理符号链接和连接
- 在信号/插槽处理过程中删除QObject
- 使用std::function和std::bind来存储回调并处理对象删除