重新分配结构数组

时间:2017-04-06 06:53:25

标签: c++ struct

我想问你如何在C ++中重新分配struct数组?

在C中有realloc非常好,但不建议在C ++中使用它。也许有些人会告诉我,我不应该使用struct数组?

好吧,在这个任务中我们不能使用任何STL容器,所以我认为struct是唯一的选择。分配,重新分配记忆和其他事情是为了实践的问题......

在下面的示例中,我编写了一个代码,我将如何使用mallocrealloc在C中执行此操作。你能给我一个如何用C ++做的建议。

感谢。

class CCompany
{
  public:
      CCompany();
      bool NewAccount(const char * accountID, int initialBalance);
      struct ACCOUNT
      {
        char *accID;
        int initialBalance;
        ...
      };      
      ACCOUNT* accounts ;
      ...
      ...     
  private:      
      int ReallocationStep = 100;
      int accountCounter = 1;
      int allocatedAccounts = 100;
      ...
}

CCompany::CCompany()
{
    accounts = (ACCOUNT*)malloc(allocatedItems*sizeof(*accounts));
}


bool CCompany::NewAccount(const char * accountID, int initialBalance)
{
    // Firstly I check if there is already an account in the array of struct. If so, return false.
    ...
    // Account is not there, lets check if there is enough memory allocated.
    if (accountCounter == allocatedAccounts) 
    {
         allocatedAccounts += ReallocationStep;
         accounts = (ACCOUNT *) realloc(accounts, allocatedAccounts * sizeof(*accounts));
    }

   // Everything is okay, we can add it to the struct array
   ACCOUNT account = makeStruct(accID, initialBalance);
   accounts[CounterAccounts] = account;

   return true;
}

4 个答案:

答案 0 :(得分:0)

如果您无法使用STL容器,也许您应该考虑使用某种列表而不是数组。基于您的代码,这可能是比在一段时间内重新分配内存更好的解决方案。

答案 1 :(得分:0)

我个人认为在C ++中不推荐realloc,但对于mallocreallocfree的许多用途,C ++中还有其他概念(比如new,placement new,delete,...),更多地将语义转移到“对象”而不是“普通记忆”。

因此,使用realloc方法仍然有效;并且 - 如果像链接列表这样的动态数据结构不是一个选择 - 实际上realloc - 隐喻是我能想到的最好的,因为它可以避免不必要的复制,删除,一次又一次地重新创建项目,同时仍然提供一个连续的块占有所有物体的记忆。

答案 2 :(得分:0)

根据其他问题+答案( 12 ),您应尽可能避免在C ++中使用mallocrealloc

这两个引用中的后一个提供了一个很好的建议:如果由于它是STL容器而不允许使用std::vector,那么std::fstream可能值得考虑替代。这表明使用文件而不依赖于依赖于过多的工作记忆可能是评估任务的预期目标。我无法查看作业标准,因此我无法说明这是否合规。

即使有你的作业标准,一些讲师也喜欢在很少或没有通知的情况下改变要求;实际上,有时候只是看到一个解决方案并不是他们想到的那些(不公平)提示这样的修改。任何促使你重新发明std::vector的评估对我来说都是愚蠢的,但如果你有两个选择,而且其中只有一个涉及你的学位,我认为你唯一的解决方案是使用realloc;这里不需要malloc

为了减少经常调用realloc的开销(如另一个答案所指出的),您可以删除三个计数器中的两个,当剩余计数器即将成为电源时调用realloc两个,并像我在push_back中那样重新分配两倍:

void *push_back(void **base, void const *value, size_t *nelem, size_t size) {
    typedef unsigned char array[size];
    array *b = *base;
    if (SIZE_MAX / sizeof *b <= *nelem) {
        return NULL;
    }

    if (*nelem & -~*nelem ? 0 : 1) {
        b = realloc(b, (*nelem * 2 + 1) * sizeof *b);
        if (!b) {
            return NULL;
        }
        *base = b;
    }

    b += (*nelem)++;
    return value
         ? memmove(b, value, sizeof *b)
         : b;
}

答案 3 :(得分:0)

正确的C ++方式是使用std::vector,它可以很好地处理重新分配。由于您的作业不允许您使用标准容器,您可以:

  • 使用new构建自定义容器,使用delete进行重新分配并基于数组或链接列表
  • 或直接使用数组并坚持使用new和delete进行重新分配 - 仍然可以接受C ++
  • 或从C ++标准库中包含的C标准库恢复到良好的旧mallocrealloc。但是你必须意识到这不会初始化结构。

因为malloc / realloc不会调用构造函数,所以必须将最后一种方法视为低级优化,并且应该明确记录无初始化。