Я работаю над программой, и у меня есть утечка памяти, которую я просто не могу прибить. Я тоже не очень разбираюсь в C/C++. Я отправлю ОДИН из ошибок valgrind и определений классов и функций, которые являются релевантными ... если я что-то забуду, просто спрошу, и я буду обновлять :) Причина, по которой я не публикую весь отчет valgrind, есть много их, но они схожи ... единственная разница - это трассировка стека.Не удается найти утечку памяти, обнаруженную Valgrind
Я начал разрабатывать его довольно плохо, поэтому, чтобы исправить утечки памяти, моя идея состояла в том, чтобы создать глобальную фабрику для добавления моих объектов, чтобы удалить их позже. Я заменил каждое появление «нового» на заводский метод для его создания .. в этом случае это класс Column. Я уверен, что каждый объект, созданный makeColumn, удаляется, поскольку я использую вектор для хранения указателя. Функция для итерации по вектору и удаления каждого элемента в нем. Вызывается до завершения программы.
Этот отчет valgrind заставляет меня думать, что каким-то образом нить не освобождается. Я устанавливаю переменную GLIBCXX_FORCE_NEW, и она не имеет никакого отношения к обнаруженным утечкам. Я использую gcc 4.7.2.
Кроме того, да, я получаю информацию от созданного ANTLR парсера ... это, вероятно, не имеет значения, поскольку ANTLR обрабатывает его собственную память. Указатели char являются единственными данными ANTLR.
==23168== 15 bytes in 1 blocks are definitely lost in loss record 10 of 30
==23168== at 0x4ACE73C: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==23168== by 0x4BA62A3: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib32/libstdc++.so.6.0.17)
==23168== by 0x4BA75EE: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) (in /usr/lib32/libstdc++.so.6.0.17)
==23168== by 0x4BA7F3F: std::string::assign(std::string const&) (in /usr/lib32/libstdc++.so.6.0.17)
==23168== by 0x4BA7F92: std::string::operator=(std::string const&) (in /usr/lib32/libstdc++.so.6.0.17)
==23168== by 0x82E0B57: GenericFactory::makeColumn(char const*, char const*, char const*) (global.cpp:246)
==23168== by 0x82DEA23: addTable (helper.cpp:93)
==23168== by 0x810DE1F: query_table_expression (OracleSQLParser.c:165181)
==23168== by 0x8108F66: table_reference (OracleSQLParser.c:162767)
==23168== by 0x81154B1: join_clause (OracleSQLParser.c:168172)
==23168== by 0x82A0845: synpred349_OracleSQL_fragment (OracleSQLParser.c:460632)
==23168== by 0x82AFA48: synpred349_OracleSQL (OracleSQLParser.c:469414)
helper.cpp: addTable - putValue просто добавляет указатель на карту.
void addTable(char* schema, char* table) {
::gbl_info->tables->putValue(::gbl_info->factory.makeColumn(schema,table,""),NULL);
}
GenericFactory :: makeColumn
Column* GenericFactory::makeColumn(const char* schema,const char* table, const char* column) {
this->count++;
Column* col = new Column(schema,table,column);
this->allocated_objects.push_back(col);
return col;
}
Колонка :: Колонка
Column::Column(const char* schema, const char* table, const char* column) {
string temp = schema;
this->schema = normalize(temp);
temp = table;
this->table = normalize(temp);
temp = column;
this->column = normalize(temp);
temp = schema;
temp = temp + "." + table + "." + column;
this->text = normalize(temp);
}
нормализуют
string& normalize(string& str) {
for (string::iterator p=str.begin(); p != str.end(); p++)
*p = toupper(*p);
str.erase(remove(str.begin(),str.end(),'"'),str.end()); // erase double quotes
return str;
}
определение столбца: SQLData не имеет членов или конструкторов
class Column : public SQLData {
std::string text;
std::string schema;
std::string table;
std::string column;
public:
std::string alias; // TABLE alias
Column(const char*,const char*,const char*);
Column(const std::string qn);
//Has functions too, but probably irrelevant
}
Я потратил часы, пытаясь исправить это, и я просто не уверен, где я теряю память ... программа может работать в течение нескольких минут или даже часов при обработке данных, и поэтому она действительно строит вверх.
Как вы определяете, что у вас есть утечка памяти? – Doug
@Doug Размер процесса достигает примерно 400 МБ после обработки 20 000 предметов ... он должен обрабатывать миллионы и продолжает расти. Поэтому я побежал к Вальгринду, чтобы найти их. Между каждым элементом нет совместного доступа - вся память должна быть удалена между ними, поэтому след памяти процесса должен быть относительно небольшим. – shaddow
В моем опыте с C++ почти каждый случай «утечки памяти» был вызван «новым», который не был сопряжен с «delete». Вы вызываете 'makeColumn()' для каждого обрабатываемого элемента? – Doug