утечка памяти strtok & amp; atof

int fromVectoEigen(vector<string> & source, double ** & array, int & n)
{
cout<<"n:"<<n<<'\n';
int counter = 0;

for (int j = n-1 ; j >= 0 ; j--) // iterate through each line
{
string mystring = source.back(); // take last line

counter++;
char * str = new char [mystring.length()+1];
std::strcpy (str, mystring.c_str()); // copy string to char array
char * pch; // pointer to tokens
pch = strtok (str," ,-");
for( int i = 0 ; i<3 ; i++) // dismiss first 3 columns
{

pch = strtok (NULL, " ,-");
}

for (int i= 0 ; i<n ; i++)
{
double val = atof(pch); // cast char to double

//array[j][i]= val;
//cout<<array[j][i]<<'\t';
//pch = strtok (NULL, " ,-");
}
//
//source.pop_back();

}

return 0;
}

Привет!

С помощью этой функции я хочу прочитать в матрице из файла в двумерный массив
В матрице столько строк, сколько столбцов. И я хочу разделить строки пробелом с помощью strtok.
Строки уже были прочитаны в вектор в другой функции. (Которая работала — это было проверено). Так что я не знаю проблему, потому что я пытался запустить это с небольшой матрицей 4 столбца 4 строки, который работал отлично! Теперь я хотел попробовать это с большой матрицей, которая имеет более 1000 строк и столько же столбцов. и я получаю это сообщение об ошибке от valgrind:

Неверное чтение размера 1
== 26501 == в 0x58A87AB: __strtod_l_internal (strtod_l.c: 538)
== 26501 == по 0x4015BB: fromVectoEigen (std :: vector>&двойной **&Int&) (topo.cpp: 70)
== 26501 == по 0x40362B: main (main.cpp: 36)
== 26501 == Адрес 0x0 не является стековым, malloc или (недавно) свободным

Я попробовал метод комментария / раскомментирования, и все прекрасно работает там, где я использую atof …. что я не понимаю, потому что он работал нормально с небольшой матрицей

Значения в большой матрице выглядят так: 0.11991517, где, как и в маленькой тестовой матрице, у меня были только значения, такие как 0 или 0,1.

Я надеюсь, что объяснил достаточно … Просьба попросить более подробную информацию, если это необходимо.

2

Решение

Вы выделяете str, но вы никогда не освобождаете это … и с кодом, который у вас есть, вы никогда не сможете. Таким образом, каждый раз, когда вы вызываете эту функцию, вы теряете память.

Вы должны либо добавить delete [] str; когда вы закончите с этим, или не используйте динамическую память вообще и придерживаться std::string,

Кроме того, вы можете избежать всей проблемы конверсии и просто использовать std::istream::operator>> (например, используя std::istringstream) для анализа вашего ввода.

Нечто подобное (непроверенное) должно работать лучше для вас:

struct reader : std::ctype<char>
{
reader() : std::ctype<char>(get_table()) {}

static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());
rc['\n'] = std::ctype_base::space;
rc[','] = std::ctype_base::space;
rc['-'] = std::ctype_base::space;
rc[' '] = std::ctype_base::space;
rc['\t'] = std::ctype_base::space;
return &rc[0];
}
};

int fromVectorEigen(const std::vector<std::string>& source, std::vector<std::vector<double>>& destination)
{
reader rdr;
std::for_each(source.rbegin(), source.rend(), [&](const std::string& s)
{
std::istringstream iss(s);
iss.imbue(std::locale(), &rdr);
std::string ignored_columns;
double value;
iss >> ignored_columns >> ignored_columns >> ignored_columns;
std::vector<double> values;
while (iss >> value)
{
values.push_back(value);
}
destination.push_front(values);
});
return 0;
}
3

Другие решения

Если вы хотите остаться с этим текущим дизайном, не использующим потоки, но исключающим явное распределение памяти, вы можете использовать std :: vector:

  #include <vector>
//...
std::vector<char> str(mystring.begin(), mystring,end());
str.push_back(0);
char * pch; // pointer to tokens
pch = strtok (&str[0]," ,-");
0

По вопросам рекламы [email protected]