【问题标题】:C++ resize array of pointer without STL (vector...)C ++调整没有STL的指针数组(向量......)
【发布时间】:2015-06-21 13:58:51
【问题描述】:

我遇到了以下问题。 我想调整结构 (car) 上的指针数组的大小。我得到了以下代码。

 Class Car{
      ...
    char * Owner_Name; 
    char * carID
    };

 Class Register {
  ...

  int CarCNT;
  int car_num_default;
  Car ** dataBase;

    Register ()
   {  //constructor
     car_num_default = 5 ; //for example;
     dataBase = new Car * [car_num_default]; 
   }

};

现在当我添加第 6 个时。 car 我需要调整指向汽车的指针数组的大小。我应该如何在不产生任何内存泄漏的情况下做到这一点?还是内存错误? :) 我尝试了以下代码,但它会导致一些内存泄漏..

void Register:: Add ( const char * carID, const char * owner)
{
   if (carCNT == car_num_default) // now it's full array need resize 
       {  
          car ** tmp = new car * [carCNT]; //create new array ; 
                for(int i = 0 ; i < carCNT;i++)
                 tmp[i] =  new car(databaze[i]->car_ID,databaze[i]->owner_name);

        free(database); //free memory and than alloc new bigger 

           database = new car * [car_num_default * 5];
            for(int i = 0; i < carCNT; i++)
             data_by_RZ[i] = tmp [i];

            free(tmp);
          car_num_def = car_num_def * 5;
    }

     databaze[carCNT] = new car(....);
     carCNT++;

}

感谢您的帮助!

【问题讨论】:

  • 这闻起来不像c
  • 坦率地说,这也不完全像 c++。没有关键字Class
  • 如果没有 STL,您总是可以在堆上分配并执行 realloc()。但是如果数组中保存的对象是类对象,你希望 new 和 delete 运行构造函数/析构函数。
  • @dragon_Lord_Of_Math 如果您不能使用 STL,请创建自己的。编写你自己的向量类(它不必拥有std::vector 的所有花里胡哨),一旦你编写了它,你就可以在“不能使用 STL”的任何地方使用它。您现在所做的 IMO 没有用,因为您所做的只是业务逻辑中间的这些一次性分配和释放例程。

标签: c++ pointers resize realloc


【解决方案1】:

以下是内存管理中明显的错误列表:

  • 您使用 new[] 分配但使用 free 解除分配。见Is there any danger in calling free() or delete instead of delete[]?
  • 在重新分配时,您创建新的汽车实例并复制现有汽车对象的数据,而不是复制指向现有汽车对象的指针。这会导致所有先前的汽车对象泄漏。此错误仅在将数据库复制到 tmp 表时出现。如果 tmp 包含指向旧汽车对象的指针,则从 tmp 到新数据库的副本是正确的。
  • 您不必要地创建了一个 tmp 数组并将数据库复制到其中。您应该简单地创建新的更大的数组,复制,释放旧的,然后设置数据库指针。此错误不会导致泄漏,但完全没有意义并且会浪费内存带宽。*

* 以下是所要求的代码:

Car** tmp = new Car*[car_num_default * 5];
for(int i = 0; i < CarCNT; i++)
    tmp[i] = database[i];
delete[] database;
database = tmp;

【讨论】:

  • 能否请您发布一些代码。我试着做“你应该简单地创建一个新的、更大的数组,复制,释放旧的,然后设置数据库指针。”之前,但解决方案是seqmentation错误...
  • @dragon_Lord_Of_Math 那你做得不对。它可能看起来像like this
【解决方案2】:

请记住,函数在执行完函数后会销毁其参数。

由于您将 carID 和 owner 作为指针传递并将它们插入到数组中,因此这些值在执行后会被破坏,并且放置在数组中的指针变得无效,从而导致泄漏。仅当您想要更改指针本身但永远不要存储它时才使用指针,因为它很快就会被破坏。

您似乎在不应该或不需要的地方使用了指针。这是您的代码的一个更简单的版本:

Class Car{
      ...
    char  Owner_Name; 
    char  carID;
    };

 Class Register {
  ...

  int CarCNT;
  int car_num_default;
  Car * dataBase;

    Register ()
   {  //constructor
     car_num_default = 5 ; //for example;
     dataBase = new Car [car_num_default]; 
   }

};
void Register:: Add ( const char  carID, const char owner)
{
   if (CarCNT == car_num_default) // now it's full array need resize 
       {  
          car * tmp = new car  [carCNT]; //create new array ; 
                for(int i = 0 ; i < carCNT;i++)
                 tmp[i] =  new car(dataBase[i].car_ID,dataBase[i].owner_name);

        free(dataBase); //free memory and than alloc new bigger 

           dataBase = new car  [car_num_default * 5];
            for(int i = 0; i < carCNT; i++)
             data_by_RZ[i] = tmp [i];

            free(tmp);
          car_num_def = car_num_def * 5;
    }
    Car x(...);
    dataBase[CarCNT] = x;
    carCNT++;

}

最后,我想说四点:

1) 这看起来不像 C++,或者你没有使用正确的命名

2) 我不确定这段代码是如何编译的,因为大多数变量名都不正确(我试图修复我遇到的问题)。

3) 过度使用指针(即内存位置)是内存泄漏的主要原因。小心处理它们,仅在必要时使用它们。

4) IFFF 您必须使用那么多指针,然后在任何用作指示元素被销毁时发出信号的指针的类上添加像 ~Car 或 ~Register 这样的析构函数(反构造函数)。这样,您可以通过写入控制台或优雅地处理破坏来了解泄漏发生的位置。

希望有所帮助

【讨论】:

    猜你喜欢
    • 2012-08-04
    • 2017-07-16
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多