Memory Leak Strtok & ATOF

memory leak strtok & atof

本文关键字:ATOF Strtok Leak Memory      更新时间:2023-10-16
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===by 0x4015B:fromVectoEigen(std::vector>&,double**&;,int&)(topo.cpp:70)===26501===通过0x40362B:main(main.cpp:36)===26501===地址0x0不是堆栈的、malloc的或(最近)空闲的

我尝试了注释/取消注释方法,直到我使用atof为止,一切都很好。。。。我不明白,因为它与小矩阵配合得很好

大矩阵中的值如下所示:0.11991517,与小测试矩阵一样,我只有0或0.1 这样的值

我希望我解释得够多了。。。如果需要,请询问更多细节。

您分配了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;
}

如果你想保持目前不使用流的设计,但消除显式的内存分配,你可以使用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]," ,-");