我用一个分配器替换了标准分配器,这个分配器将“呼叫总部”它消耗多少内存。现在我正在浏览我的一些代码,想知道为什么它会分配然后释放这么多条目。
只是作为参考,我不想预先优化我的代码或任何东西,我主要是好奇,除了我肯定需要知道我的总大小是否关闭,因为我需要知道我的对象到底有多少用于C#GC。
使用以下示例函数:
void add_file(string filename, string source) {
file_source_map.insert(std::pair<const string, string>(std::move(filename), std::move(source)));
}
它分配6次(48字节),然后释放4次(32字节)。因为这对是一个rvalue,我将字符串移到其中,所以映射肯定会分配一个新节点,并将rvalue对移到其中,而不会触发任何更多的分配,当然也不必取消任何分配。文件名和源参数也来自rvalues,应该移入,而不是复制。只需注意:分配程序也在跟踪字符串,它不是std::string,而是
std::basic_string<char, std::char_traits<char>, Allocator<char>>
.
仅供参考,我在MSVC上。
这是我的分配器代码:
template<typename T>
class Allocator {
public :
// typedefs
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
public :
// convert an allocator<T> to allocator<U>
template<typename U>
struct rebind {
typedef Allocator<U> other;
};
public :
Parser* parser;
inline ~Allocator() {}
inline Allocator(Allocator const& other) {
parser = other.parser;
}
inline Allocator(Parser* ptr)
: parser(ptr) {}
template<typename U>
inline Allocator(Allocator<U> const& other) {
parser = other.parser;
}
// address
inline pointer address(reference r) { return &r; }
inline const_pointer address(const_reference r) { return &r; }
// memory allocation
inline pointer allocate(size_type cnt,
typename std::allocator<void>::const_pointer = 0) {
int newsize = cnt * sizeof (T);
parser->size += newsize;
std::cout << "Allocated " << newsize << "\n";
return reinterpret_cast<pointer>(::operator new(newsize));
}
inline void deallocate(pointer p, size_type count) {
size_type size = count * sizeof(T);
::operator delete(p);
parser->size -= size;
std::cout << "Deallocated " << size << "\n";
}
// size
inline size_type max_size() const {
return std::numeric_limits<size_type>::max() / sizeof(T);
}
// construction/destruction
inline void construct(pointer p, const T& t) { new(p) T(t); }
inline void destroy(pointer p) { p->~T(); }
inline bool operator==(Allocator const& other) { return other.parser == parser; }
inline bool operator!=(Allocator const& a) { return !operator==(a); }
};
当我通过包装器函数从C调用add#u file(如上所述)时,我可以在控制台上清楚地看到每个分配和解除分配及其适当的大小,即4个8的分配,其中一个80来自映射,另外两个8的分配,然后4个8的解除分配,它告诉我函数中有四个多余的字符串,因为它们都是rvalues,没有理由发生任何释放。