c ++如何测试堆中的某些内存是否空闲? [英] c++ How to test whether a certain bit of memory in the heap is free?

查看:73
本文介绍了c ++如何测试堆中的某些内存是否空闲?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码:

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指向的堆中的内存是否空闲?

From the value of the pointer and the value on the memory where it pointed to, I think I can't know whether the bit of memory in the heap pointed by ip is free?

我知道,如果要在代码后再次添加delete ip;,编译器将抛出错误.这将很好地证明内存是空闲的.

I know that if I were to add delete ip; again after my code, the compiler will throw an error. That will be a good evidence that the memory is free.

但是,我如何测试它是否和平释放,以便可以将其用作决定代码中进一步操作的条件?

But, how can I test whether it's free peacefully, so that I can use it as a condition to decide further operations in my code?

推荐答案

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

You probably have some design issues if your code depends on whether specific memory is free or not. But, if you indeed want to test, you can overload operator new and operator delete (and their corresponding array/class versions) so they keep track of which memory locations are allocated in some global data structure available to your program. Here is some toy example (live on ideone.com) which defines a placement new that keeps track of what memory (and size) was allocated.

#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();
}

编辑:我意识到上面的代码可能存在一些问题.在功能

I realized that there may be some issues with the code above. In the function

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

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

memory.erase(p) calls also operator delete, so you may end up with some nasty recursion (for some reason, the code above only enters the recursion once). A fix is to write a custom allocator for the std::map memory that uses malloc/free instead of global operator new/delete.

这篇关于c ++如何测试堆中的某些内存是否空闲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆