LINUX.ORG.RU

valgrind + STL


0

0

Есть такой вот кусочек кода:

unsigned int i;
for(i=0;i<v.size();i++)
{
    packet.header.push_back(v[i]);
}

Где:
vector<char*> v;
struct Packet
{
	vector<string> header;
	string data;
};

Т.е задача этого куска кода загнать строки в string`s и с чистой
 совестью освободить память, на которую указывают указатели из v.

Valgrind же на такое дело говорит:
==11813== 58 bytes in 3 blocks are possibly lost in loss record 3 of 4
==11813==    at 0x402377E: operator new(unsigned) (vg_replace_malloc.c:224)
==11813==    by 0x40D5BB3: std::string::_Rep::_S_create(unsigned, unsigned, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.10)
==11813==    by 0x40D6814: (within /usr/lib/libstdc++.so.6.0.10)
==11813==    by 0x40D6985: std::string::string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.10)
==11813==    by 0x80505D8: Client::readPacket() (client.cpp:296)
==11813==    by 0x8050CD4: Client::processClient(short, Client*) (client.cpp:448)
==11813==    by 0x806533E: main (s_fight.cpp:317)

Варианты типа packet.header.push_back(string(v[i]));
или с временной переменной, которая уже загонется в вектор дают
такие же ошибки...

Я где-то туплю.
Подскажете где?
★★☆

#include <list>
#include <string>
       
using namespace std;

int main()
{
    
    char *str="blablabla";
        
    list<string>lis;
    string res=string(str);
    lis.push_back(res);
    
    return 0;
}

Кстати, такой вариант работает без ошибок.

Stahl ★★☆
() автор топика
Ответ на: комментарий от Stahl

#include <list>
#include <string>
#include <stdlib.h>
#include <string.h>

       
using namespace std;

int main()
{
    
    
    char *str=(char*)malloc(10);
    memcpy(str,"012345678\0",10);
        
    list<string>lis;
    string res=string(str);
    lis.push_back(res);
    
    free(str);
    
    return 0;
}

Тут тоже всё das ist gut...
Хотя это вариант, как мне кажется, ничем не отличается вообще...:(

Stahl ★★☆
() автор топика

>packet.header.push_back(v[i]); - копирует C-строку из вектора v в std::string. Может быть, перед удалением вектора v не удаляются C-строки из него?

anonymous
()

Код нормальный. Может быть используется какой то хитрый аллокатор, который не вызывает free на используемую память?

Legioner ★★★★★
()

а почему все за list схватились?

#include <list>
#include <string>
using namespace std;
int main(int argv, const char **argc)
{
    list<string> v;

    for(const char **c = argc; *c; ++c) v.push_back(*c);

    return 0;
}


#include <vector>
#include <string>
using namespace std;
int main(int argv, const char **argc)
{
    vector<string> v;
    v.reserve(10)

    for(const char **c = argc; *c; ++c) v.push_back(*c);

    return 0;
}

valgrind ./list 1 2 3 4 5 6 7 8 9 - malloc/free: 20 allocs, 20 frees, 265 bytes allocated.

valgrind ./vect 1 2 3 4 5 6 7 8 9 - malloc/free: 11 allocs, 11 frees, 185 bytes allocated.

anonymous
()

>> и с чистой совестью освободить память, на которую указывают указатели из v.

Нужно либо самостоятельно очищать память, либо завернуть эти указатели внутрь умных указателей. vector не обладает телепатией и не может догадаться что на указателях которые в нём хранятся ещё и free нужно сделать =).

Deleted
()
Ответ на: комментарий от Stahl

unsigned int i;
for(i=0;i<v.size();i++)
{
    packet.header.push_back(v[i]);
    free(v[i]);
}

Даёт аналогичный результат.

Stahl ★★☆
() автор топика
Ответ на: комментарий от Stahl

Приведи минимальный кусок кода на котором проявляется проблема и который можно откомпилировать и запустить.

Reset ★★★★★
()
Ответ на: комментарий от Reset

Разобрался.
В общем приведенный кусок кода вызывался достаточно глубоко и
exit() , соответственно, не давал возможности подчистить некоторые
локальные переменные руками.

Впрочем есть еще один кусок кода. Это я оставил на сладкое.
ДОстаточно небольшой и понятный.
Если не получится кину сюда...
Там совсем прикольно.

Stahl ★★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.