在内存泄漏等方面还不错

时间:2011-11-15 10:02:34

标签: c++ pointers memory-leaks dynamic-memory-allocation

自从我开始学习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等,因为项目只是关于指针。如果没有它们,我怎么能纠正这个

6 个答案:

答案 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)

  1. 通过分配给firstPtr将无法释放覆盖指针后面的内存
  2. 删除tempPtr您使firstPtr指向的数据无效(输出错误的直接原因)
  3. 解决方案:

    1. 在分配行“firstPtr = tempPtr;”
    2. 之前添加行以删除firstPtr
    3. 移动删除{cout&lt;&lt;“以下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指针读取值。