2017-04-06 99 views
0

我想问你如何在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; 
} 
+0

如果你不想使用'realloc',当'new'可用时,你应该重新考虑使用'malloc'。你应该为更大的尺寸执行'new',复制你已有的内容,然后'delete []'。还要非常小心你的'CCompany'类正在接受字符串的指针并将它们存储为非拥有的(即不需要拷贝)。 –

+0

是的,当然,而不是malloc我会使用新的,但我不确定与realloc。 –

+0

如果在C++中有一个realloc相当于它会杀死它的踪迹中的异常安全。分配新内存后,您希望旧数据仍然存在。分配可能会导致代码处于不一致状态。你应该分配新的块,一旦你知道成功了,然后复制到新块中,然后删除旧块。 –

回答

0

如果你没有可能使用STL容器,也许你应该考虑使用某种列表而不是数组。根据你的代码,这可能会比重复分配内存更好的解决方案。

+0

我们不能使用列表或向量,否则我会 –

+0

@TheDoctorBombastic,我不是在谈论STL列表。您可以编写自己的代码并添加必要的函数来迭代它,添加,计数和删除元素。 – Rapid

+0

当然可以:-)我可以开发一个新系统,并成为世界上最富有的人 - 无论如何,我正在学习它。我在学习的第一年,我无法做类似于创建我自己的列表的事情:-)我一直在用C++编程1.5个月...... :) –

0

个人而言,我不认为realloc不是在C++中建议,但对于mallocreallocfree有C++中的其他概念(如新,布局新,删除,...),移多种用途语义更多地在“对象”上而不是“普通内存”上。

因此,使用realloc的方法仍然有效,而且 - 如果像链表这样的动态数据结构不是一种选择 - 实际上我能想到的最好,因为它可以避免不必要的复制,删除,重复创建项目,同时仍然提供连续的内存块对象。

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; 
} 
0

正确的C++的方法是使用一个std::vector可与再分配处理很好。当你的任务不允许你使用标准集装箱,您可以:

  • 或者使用新建立一个自定义的容器和删除的重新分配和基于数组或一个链表
  • 或直接使用数组和坚持新的和删除重新分配 - 仍然可以接受的C++
  • 或恢复到C++标准库中包含的C++标准库中的旧版本mallocrealloc。但是你必须意识到这不会初始化结构。

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