【问题标题】:How do I remove (release the memory) object from an array of objects (dynamique memory allocation of objects)如何从对象数组中删除(释放内存)对象(对象的动态内存分配)
【发布时间】:2017-05-13 21:00:01
【问题描述】:

我正在使用类在 C++ 中克隆太空侵略者游戏。我希望当激光与外星人(存储在对象数组中)接触时,释放包含该外星人的内存,并将该外星人右侧的所有内存移动 1 个点,之后我想要创建一个较小的临时数组来存储剩余的对象,这样我就可以删除原始内存然后指向临时内存。 (这似乎是一个漫长的过程,但它使我不必在整个游戏中检查 isAlive 布尔值,并使搜索功能更有效)。

这是我目前所拥有的:

Ennemi::Ennemi() :ExtraTerrestre(0, 0) {

    maxElements = 1; // int maxElements
    nbElements = 0; // int nbElements
    ptr = new Ennemi*[maxElements]; // (Ennemi **ptr)
}

int Ennemi::chercherElement(Ennemi element[]){

    int indice = 0;
    while (indice < nbElements && ptr[indice] != element)
        indice++;

    // opérateur ternaire, retourne l'indice si vrai, sinon retourne -1
    return indice < nbElements ? indice : -1;
}

void Ennemi::retirerEnnemi(Ennemi element[]) {
    int indice = chercherElement(element);

    // si un element est trouver active la condition
    if (indice != -1) {
        // preserver l'ordre du tableau
        for (int i = indice; i < (nbElements - 1); i++) {
            ptr[i] = ptr[i + 1];
        }
        nbElements--;
        maxElements = nbElements;

        // allocation d'une zone memoire
        double *ptrTemporaire = new double[maxElements];

        // copie des elements dans la nouvelle zone
        for (int i = 0; i < nbElements; i++) {
            ptrTemporaire[i] = ptr[i];
        }
        // on libere l'ancienne zone memoire
        delete[] ptr;

        // fait pointer le pointeur sur la nouvelle zone
        ptr = ptrTemporaire;
    }
}

附:请不要建议使用向量,我正在努力提高我的理解,而不是简单的方法。

【问题讨论】:

  • 这不是唯一的错误,您的代码不可编译而且非常混乱。如果您想使用原始数组,则需要更好地理解该主题。
  • 缓冲区是Ennemi **ptr 还是Ennemi element[]?从您的代码中不清楚。

标签: c++ arrays object memory memory-management


【解决方案1】:

我的建议是创建一个链表结构,这样您就可以轻松释放内存并转移成员。

【讨论】:

    【解决方案2】:

    首先这个函数可能正常工作,但设计得很糟糕:

    int Ennemi::chercherElement(Ennemi element[]);
    

    此函数假设通过指针查找元素的索引,但您的函数名称是findElement(请原谅我的法语)并且您传递元素数组。虽然在语法上它是相同的,但它会混淆包括你自己在内的读者,所以它应该是:

    int Ennemi::findElementIndex( Ennemi *element );
    

    (或翻译回法语)现在为了使其完全正确,我们应该注意到此方法不会更改 element 或内部数据,所以

    int Ennemi::findElementIndex( const Ennemi *element ) const;
    

    现在您从数组中擦除数据,您的代码几乎是正确的,但您缺少删除对象本身的代码:

        if (indice != -1) {
           delete ptr[i]; // this missing
           // preserver l'ordre du tableau
           for (int i = indice; i < (nbElements - 1); i++) {
               ptr[i] = ptr[i + 1];
           }
           nbElements--;
       }
    

    在您尝试收缩动态分配的数据之后,不要这样做。分配/取消分配内存是一项非常昂贵的操作,因此通常您在没有足够空间时进行扩展(并且您不应该扩展一个,而是一些增量)并且您不会收缩,因为您很有可能必须重新增长再次。或者你至少可以缩小一些增量。例如,当元素数量 == maxElemens / 2 时。

    还有这一行:

     double *ptrTemporaire = new double[maxElements];
    

    您尝试创建双精度数组并将其分配给指向Ennemi 的指针数组,这绝对是错误的。

    【讨论】:

    • 非常感谢。是的,我忘记在移动值之前删除有问题的对象。是的,你的权利我不需要逐个缩小内存,只跟踪外星人的数量(并减少搜索限制)然后将内存缩小一些增量会更有效,并且我确实考虑过使用 *element (指向区域的值),但由于某种原因它并没有在我的脑海中连接:(。这些概念仍然很新,但还是非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2012-05-04
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    相关资源
    最近更新 更多