나는 표준 할당자를 얼마나 많은 메모리를 소비하는지에 대해 "전화 집으로 돌아 가게"할 할당 자로 바꿨다. 이제는 내 코드 중 일부를 살펴보고 왜 그렇게 많은 항목을 할당하고 할당을 해제하는지 궁금해합니다.STL에서 여분의 할당과 마 법적 공간 축소 - rvalue 참조 사용
참조 용으로 코드를 미리 최적화하려고하지 않습니다. 내 총 크기가 꺼져 있는지 확실히 알 필요가 있다는 것을 제외하고는 대부분 궁금합니다. 개체가 C# GC에 사용 중입니다.
void add_file(string filename, string source) {
file_source_map.insert(std::pair<const string, string>(std::move(filename), std::move(source)));
}
그것은 여섯 번 (48bytes)를 할당하고, 그 다음 네 번 (32 바이트)를 할당 해제 :
이 샘플 기능을 가지고. 쌍이 rvalue이고 문자열을이 필드로 옮겼으므로 확실히 맵은 새로운 노드를 할당하고 더 이상 할당을 트리거하지 않고 임의의 할당을 해제하지 않고도 rvalue 쌍을이 노드로 이동합니다. 파일 이름과 소스 인수도 rvalues에서 가져오고 복사해야합니다. 단지 참고 사항 : 문자열도 할당자가 추적합니다. std :: string은 아니지만std::basic_string<char, std::char_traits<char>, Allocator<char>>
입니다.
참조 용으로, 저는 MSVC에 있습니다.
여기 내 할당 코드이다 : 나는 래퍼 함수를 통해 C에서 # add_file (위 게시)를 호출 할 때
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); }
};
, 나는 각각의 할당 및 할당 취소하고 콘솔에서 자신의 적절한 크기를 명확하게 볼 수 있고, 즉 4 개의 할당 8 개, 80 개 중 하나가지도에서 나오고 8 개는 2 개 더 할당 된 다음 8 개는 4 개 할당 해제됩니다. 이는 함수에 4 개의 중복 문자열이 있다고 말합니다. 할당 해제가 발생할 이유가 없습니다.
노드를 16 바이트로 맞추는 것을 "알았습니까"? 당신 할당 자 때문인가요? 아마도 문제는 "마법"STL 코드보다는 할당 자 로직에 있습니다. –
@Peter : 할당 자 논리는 매우 간단합니다. count * sizeof (T)를 할당하면 countof * sizeof (T)의 할당을 해제합니다. 할당을 잘못 추적했다면 STL 코드가 가지고있는 것보다 더 많은 메모리가 필요할 때 충돌이 발생하고 할당 해제를 잘못 추적하면 메모리 누수가 발생합니다. – Puppy
@DeadMG : 할당 자의 관련 코드와 16 바이트/노드를 나타내는 코드를 게시하는 것이 좋습니다. –