c++如何测试堆中的某一位内存是否空闲?

标签 c++ pointers memory heap-memory

我有一些代码:

int *ip = new int;

*ip = 42;
cout << *ip << endl;
cout << ip << endl;

delete ip;
cout << *ip << endl;
cout << ip << endl;

输出是:

42
0x100105400
42
0x100105400

从指针的值和它指向的内存上的值,我想我无法知道ip指向的堆中的那 block 内存是否空闲?

我知道如果我在我的代码后再次添加 delete ip;,编译器会抛出错误。这将是内存空闲的一个很好的证据。

但是,我怎样才能和平地测试它是否免费,以便我可以将它作为一个条件来决定我的代码中的进一步操作?

最佳答案

如果您的代码取决于特定内存是否空闲,您可能会遇到一些设计问题。但是,如果您确实想要测试,您可以重载 operator newoperator delete(以及它们相应的数组/类版本),以便它们跟踪分配了哪些内存位置在您的程序可用的某些全局数据结构中。这是一些玩具示例 ( live on ideone.com ),它定义了一个位置 new 来跟踪分配的内存(和大小)。

#include <iostream>
#include <map>

std::map<void*, std::size_t> memory; // globally allocated memory map
struct tag {}; // tag for placement new's so we don't overload the global ones

void* operator new(std::size_t size, const tag&)
{
    void* addr = malloc(size);
    memory[addr] = size;
    return addr;
}

void* operator new[](std::size_t size, const tag&) // for arrays
{
    return operator new(size, tag());
}

void operator delete(void *p) noexcept
{
    memory.erase(p);
    free(p);
}

void operator delete[](void *p) noexcept // for arrays
{
    operator delete(p);
}

void display_memory()
{
    std::cout << "Allocated heap memory: " << std::endl;
    for (auto && elem : memory)
    {
        std::cout << "\tADDR: " << elem.first << " "
                  << "SIZE: "  << elem.second << std::endl;
    }
}

bool is_allocated(void* p)
{
    return (memory.find(p) != memory.end());
}

int main()
{
    int *p = new(tag()) int[10];
    char *c = new(tag()) char;

    // test if p is allocated
    std::cout << std::boolalpha << "Allocated: "
              << is_allocated(p) << std::endl;

    // display the allocated memory
    display_memory();

    // remove p
    delete[] p;

    // test again if p is allocated
    std::cout << std::boolalpha << "Allocated: "
              << is_allocated(p) << std::endl;

    display_memory();

    // remove c
    delete c;

    display_memory();
}

编辑:我意识到上面的代码可能存在一些问题。在函数中

void operator delete(void *p) noexcept
{
    memory.erase(p);
    free(p);
}

memory.erase(p) 还调用了 operator delete,因此您最终可能会遇到一些讨厌的递归(出于某种原因,上面的代码只进入递归一次).解决方法是为 std::map 内存 编写一个自定义分配器,它使用 malloc/free 而不是全局 operator new/delete

关于c++如何测试堆中的某一位内存是否空闲?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29820626/

相关文章:

C++ if else 语句一直执行 if 而不是 else 下的代码

c++ - 用于 pod 的重载运算符 ==

iphone - 关于释放分配的内存的简单问题

C++ 使用任意数量的变量调用函数指针

c++ - 如何在另一个正在运行的进程中找到自定义函数的地址以 Hook /绕行?

c++ - 从 __m256 选择元素子集?

c++ - Opencv:在轮廓图像中填充颜色

c - 如何在不使用 & 符号的情况下将指针转换为字符?

c++ - C/C++ 全局变量唯一性?

c - 如何通过函数更改数组