自从我开始学习c ++以来已经过去了大约两个月,而且我不太确定我的项目是否错误。我有一个动态分配的数组,其初始大小和我想改变它的大小后。我想知道的是为什么以下代码错误
int *firstPtr = new int [4];
for (int i = 0; i < 4; i++) {
firstPtr[i] = i;
}
int *tempPtr = new int[5];
for (int i = 0; i < 4; i++) {
tempPtr[i] = firstPtr[i];
}
tempPtr[4] = 4;
// firstPtr = new int[5];
firstPtr = tempPtr;
delete tempPtr;
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
因为输出是:
10757752
10753936
2
3
4
PS:我不能使用realloc / malloc等,因为项目只是关于指针。如果没有它们,我怎么能纠正这个
答案 0 :(得分:3)
firstPtr = tempPtr;
第一个Ptr现在指向与tempPtr相同的内存。
delete tempPtr;
您现在正在删除该内存,firstPtr和tempPtr指向的内存相同。
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
您正在访问已删除的内存,打印的值可以是任何内容。
要获得我想要的内容,您需要删除该行
firstPtr = tempPtr;
或删除for:
后的内存for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
delete[] tempPtr;
请注意,在第二种情况下,您将收到内存泄漏,因为firstPtr
最初指向的内存不再可访问。
完整正常的代码如下:
int *firstPtr = new int [4];
for (int i = 0; i < 4; i++) {
firstPtr[i] = i;
}
int *tempPtr = new int[5];
for (int i = 0; i < 4; i++) {
tempPtr[i] = firstPtr[i];
}
tempPtr[4] = 4;
for (int i = 0; i < 5; i++) {
cout << firstPtr[i] << endl;
}
delete[] tempPtr;
delete[] firstPtr;
一些ASCII艺术:
firstPtr = new int[4];
firstPtr
|
+------++------++------++------+
| || || || |
| || || || |
+------++------++------++------+
for (int i = 0; i < 4; i++) {
firstPtr[i] = i;
}
firstPtr
|
+------++------++------++------+
| 0 || 1 || 2 || 3 |
| || || || |
+------++------++------++------+
int *tempPtr = new int[5];
for (int i = 0; i < 4; i++) {
tempPtr[i] = firstPtr[i];
}
tempPtr[4] = 4;
tempPtr
|
+------++------++------++------++------+
| 0 || 1 || 2 || 3 || 4 |
| || || || || |
+------++------++------++------++------+
所以现在,在记忆中,你有:
firstPtr
|
+------++------++------++------+
| 0 || 1 || 2 || 3 |
| || || || |
+------++------++------++------+
tempPtr
|
+------++------++------++------++------+
| 0 || 1 || 2 || 3 || 4 |
| || || || || |
+------++------++------++------++------+
你的下一行:
firstPtr = tempPtr;
这样做:
no longer pointed to by firstPtr
|
+------++------++------++------+
| 0 || 1 || 2 || 3 |
| || || || |
+------++------++------++------+
tempPtr
firstPtr - firstPtr now points here
|
+------++------++------++------++------+
| 0 || 1 || 2 || 3 || 4 |
| || || || || |
+------++------++------++------++------+
delete tempPtr;
tempPtr
firstPtr - firstPtr now points here
|
+------++------++------++------++------+
| x || x || x || x || x |
| || || || || |
+------++------++------++------++------+
所以现在,tempPtr指向删除内存。希望这可以解决问题。
答案 1 :(得分:1)
firstPtr
将无法释放覆盖指针后面的内存tempPtr
您使firstPtr
指向的数据无效(输出错误的直接原因)解决方案:
firstPtr
tempPtr
的行环答案 2 :(得分:1)
就在这里
firstPtr = tempPtr;
delete tempPtr;
你看,你将tempPtr
的值赋给firstPtr
,这意味着它们指的是相同的内存位置(此时你没有指向旧内存的指针,这是使用的要由firstPtr
指向,然后你释放delete
tempPtr
指向的内存,实际上是相同的内存。
正确的方法应该是
delete firstPtr;
firstPtr = tempPtr;
答案 3 :(得分:0)
而不是
firstPtr = tempPtr;
delete tempPtr;
你需要
delete [] firstPtr;
firstPtr = tempPtr;
之后,在你完成之后,不要忘记
delete [] firstPtr;
在你的原始帖子中,你首先在新分配的memore上获得你的firstPtr点,然后释放它。所以firstPtr和tmpPrt都指向释放的内存。使用释放的内存是未定义的行为。另外,请考虑使用std::vector<int>
s。这会让你的生活更轻松。
答案 4 :(得分:0)
firstPtr = tempPtr;
delete tempPtr;
然后你使用firstPtr
,但它与你删除的指针tempPtr
相同。
尝试在纸上绘图,了解堆内部发生的事情。
答案 5 :(得分:0)
您正在访问已删除的内存。这是未定义的行为。
这类似于在调用malloc()
后从free()
ed指针读取值。