【问题标题】:How to reallocate memory anyhow, even if realloc() failed in c++即使 realloc() 在 C++ 中失败,如何重新分配内存
【发布时间】:2019-11-01 21:33:50
【问题描述】:

使用 malloc() 成功分配后,有时程序需要增加数组的大小。虽然 malloc() 成功了,但是 realloc() 失败了。

我已经使用这段代码来处理 realloc() 的失败。 这里 T 是模板参数。 array是T类型的指针,_size是数组已经被使用的总索引,_maxSize是最大可用索引数. 当_size达到_maxSize时需要重新分配

if(_size == _maxSize){
    _maxSize *= 2;
    T *temp;
    temp = (T *) realloc( array, sizeof( T ) * (_maxSize) ) ;
    if(temp == NULL){
        printf("...reallocation of memory failed...\n");
        exit(0);
    }
    else{
        array = temp;
    }
}

虽然处理了realloc()的失败,但程序确实需要增加数组大小,我真的不知道即使realloc()失败了如何执行重新分配。

【问题讨论】:

  • C 还是 C++?答案不一样!
  • 这段代码是用c++写的@BasileStarynkevitch
  • 您是否认为分配器出于恶意拒绝分配,并且您可以通过realloc以外的其他方式访问某个隐藏的内存存储区?
  • "这里 T 是模板参数" - 所以代码是 C++,即使它使用了一种非常 C 风格的分配方式记忆
  • 注意(与问题无关):如果这是c++并且T是模板类型,那么您必须非常小心地手动调用其放置构造函数/ 析构函数在正确的时间 - 你没有提供所有的代码,所以我们无法验证你正在这样做。事实上,使用realloc 甚至没有给你机会做对——它有时会移动内存,你不会有机会调用析构函数。您只是不想这样做 - 它只能在有限的场景中工作,而且太危险了。

标签: c++ pointers dynamic-memory-allocation realloc


【解决方案1】:

如何重新分配内存,即使 realloc() 在 c++ 中失败

在真正的 C++ 中,您从不使用 mallocrealloc,只使用 new(在您的 C++ standard library 实现中实现,并将在内部调用 malloc!)和delete(它通常调用free),最好是standard containerssmart pointers。内存不足的情况由异常处理(例如std::bad_alloc),您可以catch 这些异常。

在 C 中,稳健的解决方案是不使用 realloc,而只使用 malloccallocfree(使用 memset 来清除该区域,以及memcpy复制它)。

真正的问题是如何巧妙地处理内存不足的情况。这是一个设计问题,并且是特定于应用程序的。请注意memoizationgarbage collection 技术、概念 和术语。请注意reference counting 是一种原语,但经常用于 C++ 垃圾收集技术。所以请阅读GC handbook 或至少tracing garbage collection wikipage,了解它会教给你的概念

注意memory over-commitment。这是我不喜欢的操作系统功能。

还要注意mallocfree(在您的C standard library 实现中实现)正在使用操作系统原语(通常是system calls)。因此,请阅读有关操作系统的更多信息,例如Operating Systems: Three Easy Pieces。在 Linux 上,这些操作系统原语(经常)是mmap(2)munmap(2)。因为系统调用代价高昂,你的标准库会尽量避免它们,并且更愿意将free-d 内存区域标记为将来可重用malloc-s。

使用valgrind 追捕memory leaks。你宁愿在Linux distribution 上开发你的 C++ 代码,只是为了拥有valgrind。我的观点是 Linux 提供了一个对开发人员非常友好的软件环境,所以我向大多数程序员和学生推荐 Linux。不要忘记使用g++ -Wall -g 进行编译(可能还有-O2,在进行基准测试时)并在需要时使用address sanitizer

更一般地,阅读http://norvig.com/21-days.html - 它提供了一个绝妙的见解。

【讨论】:

    猜你喜欢
    • 2020-05-01
    • 1970-01-01
    • 2021-05-06
    • 2020-01-31
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多