Как работает с памятью std::map ?
От: LanOK  
Дата: 17.05.12 21:15
Оценка:
Написал пограммку:


#include <iostream>
#include <string>
#include <map>

int main(){
    std::string str("12356789012356789012345678901234567890");
    std::map<std::string, int> m;
    m.insert(std::pair<std::string, int> (str, 1));
}


запустил под valgrind-ом:
$ valgrind --leak-check=yes ./a.out 
==12585== Memcheck, a memory error detector
==12585== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12585== Using Valgrind-3.8.0.SVN and LibVEX; rerun with -h for copyright info
==12585== Command: ./a.out
==12585== 
==12585== 
==12585== HEAP SUMMARY:
==12585==     in use at exit: 0 bytes in 0 blocks
==12610==   total heap usage: 2 allocs, 2 frees, 111 bytes allocated
==12585== 
==12585== All heap blocks were freed -- no leaks are possible
==12585== 
==12585== For counts of detected and suppressed errors, rerun with: -v
==12585== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)


Подумал, а что если поменять std::map<std::string, int> на std::map<std::string*, int, Comp>, ведь поидее должен быть профит по памяти на длиннных строках.
#include <iostream>
#include <string>
#include <map>

struct Comp {    
        bool operator() (std::string* lhs, std::string* rhs) const
                {return *lhs < *rhs;}
};

int main(){
    std::string str("12356789012356789012345678901234567890");
    std::map<std::string*, int, Comp> m;
    m.insert(std::pair<std::string*, int> (&str, 1));
}

Запустил под valgrind-ом:

$ valgrind --leak-check=yes ./a.out 
==12563== Memcheck, a memory error detector
==12563== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12563== Using Valgrind-3.8.0.SVN and LibVEX; rerun with -h for copyright info
==12563== Command: ./a.out
==12563== 
==12563== 
==12563== HEAP SUMMARY:
==12563==     in use at exit: 0 bytes in 0 blocks
==12633==   total heap usage: 2 allocs, 2 frees, 111 bytes allocated
==12563== 
==12563== All heap blocks were freed -- no leaks are possible
==12563== 
==12563== For counts of detected and suppressed errors, rerun with: -v
==12563== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)


Но как видно всё то же: "111 bytes allocated".
Вот и возник вопрос, а почему?
Re: Как работает с памятью std::map ?
От: Vamp Россия  
Дата: 17.05.12 21:24
Оценка: 2 (1)
LOK>Написал пограммку:

int main(){
    std::string str("12356789012356789012345678901234567890");
    std::map<std::string, int> m;
    m.insert(std::pair<std::string, int> (str, 1));
}


LOK>==12610== total heap usage: 2 allocs, 2 frees, 111 bytes allocated



LOK>Подумал, а что если поменять std::map<std::string, int> на std::map<std::string*, int, Comp>, ведь поидее должен быть профит по памяти на длиннных строках.

int main(){
    std::string str("12356789012356789012345678901234567890");
    std::map<std::string*, int, Comp> m;
    m.insert(std::pair<std::string*, int> (&str, 1));
}

LOK>==12633== total heap usage: 2 allocs, 2 frees, 111 bytes allocated

LOK>Вот и возник вопрос, а почему?

Cкорее всего из-за оптимизации в std::string. При создании копии твоей длинной строки реально строки не копируются, а вместо этого используется общий указатель.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Как работает с памятью std::map ?
От: LanOK  
Дата: 17.05.12 21:38
Оценка:
Спасибо, Vamp.
Похоже так и есть,
Добавил в первую программу в конце изменение исходной строки, и память увеливилась:
#include <iostream>
#include <string>
#include <map>


int main(){
    std::string str("12356789012356789012345678901234567890");
    std::map<std::string, int> m;
    m.insert(std::pair<std::string, int> (str, 1));
    str = "0987654321098765432109876543210987654321";
}


$ valgrind --leak-check=yes ./a.out 
==12795== Memcheck, a memory error detector
==12795== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12795== Using Valgrind-3.8.0.SVN and LibVEX; rerun with -h for copyright info
==12795== Command: ./a.out
==12795== 
==12795== 
==12795== HEAP SUMMARY:
==12795==     in use at exit: 0 bytes in 0 blocks
==12795==   total heap usage: 3 allocs, 3 frees, 212 bytes allocated
==12795== 
==12795== All heap blocks were freed -- no leaks are possible
==12795== 
==12795== For counts of detected and suppressed errors, rerun with: -v
==12795== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.