【问题标题】:Transfer Dynamic Array to new Dynamic Array, Delete Dynamic array filled with Dynamic Objects将动态数组转移到新的动态数组,删除用动态对象填充的动态数组
【发布时间】:2021-07-18 18:50:57
【问题描述】:

如果我创建了一个 Zebras 的动态数组,然后说,我创建了一个新的 Temp 数组,我想在其中传输原始数组中的对象。

然后我将指针从原始数组移动到临时。在 move array = temp 之前我需要删除旧的数组项吗?

另外,我似乎泄漏但不知道为什么,我似乎删除了数组和指针。

class Zebra {

public:
    //int age = 0;

};

int main() {
    
    Zebra** array = new Zebra * [10];

    for (int i = 0; i < 10; i++) {
        array[i] = new Zebra;
    }

    Zebra** temp = new Zebra * [20];
    for (int i = 0; i < 10; i++) {
        temp[i] = array[i];
    }
    // do i need to delete the old array items before move array = temp?
    array = temp;
    delete[]temp;
    temp=NULL;

    for (int i = 0; i < 10; i++) {
        delete[]array[i];
        array[i]=NULL;
    }

    
    delete[]array;

    array= NULL;
}

【问题讨论】:

  • 显而易见的问题是——你为什么不使用std::vector?为什么要制造方向盘而不是使用已经内置在汽车中的方向盘?
  • CS入门,学习指点

标签: c++ arrays memory dynamic


【解决方案1】:

你有你想要向后删除的东西:

    delete[] array;
    array = nullptr;
    
    array = temp;

    for (int i = 0; i < 10; i++) {
        delete array[i];
        array[i] = NULL;
    }
    delete[] array;
    array = NULL;

请注意,您还对 delete[] 的使用不匹配,其中应该单独使用 delete 来释放 array[i] 元素。

为什么会这样?

最初,您为指针array 分配创建一个内存块,其中包含十个指向Zebra 的指针。然后,当您创建两倍于array 的temp 并将array 中的每个指针分配给temp 时,您的temp 将保存每个array[i] 的起始地址(其中0 &lt;= i &lt; 10)。

你所做的只是delete[] array,它释放了为10指向Zebra的指针保存原始存储的内存块。当您现在分配array = temp; 时,数组指向20 的新内存块@ 指向Zebra。

所以在你的重新分配方案中,你刚刚创建了一个更大的指针块,从array全部分配到temp,删除了原来的指针块,并将新的指针块分配给array(完成)。 (基本上是在做 realloc() 在 C 中所做的事情)

完整的例子是:

#include <iostream>

class Zebra {

public:
    //int age = 0;

};

int main() {
    
    Zebra **array = new Zebra*[10];

    for (int i = 0; i < 10; i++) {
        array[i] = new Zebra;
    }

    Zebra **temp = new Zebra*[20];
    for (int i = 0; i < 10; i++) {
        temp[i] = array[i];
    }
    
    delete[] array;
    array = nullptr;
    
    array = temp;

    for (int i = 0; i < 10; i++) {
        delete array[i];
        array[i] = nullptr;
    }
    delete[] array;
    array = nullptr;
}

内存使用/错误检查

valgrind ./bin/zebra
==22402== Memcheck, a memory error detector
==22402== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22402== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==22402== Command: ./bin/zebra
==22402==
==22402==
==22402== HEAP SUMMARY:
==22402==     in use at exit: 0 bytes in 0 blocks
==22402==   total heap usage: 13 allocs, 13 frees, 72,954 bytes allocated
==22402==
==22402== All heap blocks were freed -- no leaks are possible
==22402==
==22402== For counts of detected and suppressed errors, rerun with: -v
==22402== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

【讨论】:

  • 谢谢你的解释,最后一个问题。当您说“您所做的只是删除 [] 数组,它释放了为 10 个指针保存原始存储的内存块”时,这实际上并没有删除包括所有 10 个索引的整个数组,而只是删除了内存位置指向由 10 个索引组成的数组?
  • 当然,很乐意为您提供进一步帮助。为pointer** 分配时,这是一个两步过程,您分配一个指针块,然后循环分配pointer 的任何类型的块。当你分配pointer**的新块时,你只需将旧的元素块依次复制到新块中的每个指针上,然后删除原来的指针块即可。
  • 回想一下,您已经复制了您使用temp[i] = array[i]; 分配的所有array[i] 的起始地址。因此,每个temp[i] 指向分配给array[i] = new Zebra; 的内容当您delete[] array; 时,为array[i] 分配的所有块都不会受到影响。他们现在由temp[i] 引用。因此,当您分配 array = temp; 时,您可以像以前一样引用 temp[i](现在是 array[i]),并且在完成该内存之前不要删除元素块。
  • 太好了,谢谢你的解释!很有帮助。
  • 不客气。祝你编码好运!
猜你喜欢
  • 1970-01-01
  • 2017-05-20
  • 2015-08-15
  • 2012-02-09
  • 2016-04-12
  • 2019-08-07
  • 2019-11-27
  • 2015-05-21
  • 1970-01-01
相关资源
最近更新 更多