内存泄漏strtok& ATOF

时间:2014-02-13 21:36:40

标签: c++ valgrind strtok 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 == by 0x4015BB:fromVectoEigen(std :: vector&gt;&amp;,double **&amp;,int&amp;)(topo.cpp:70)   == 26501 == by 0x40362B:main(main.cpp:36)   == 26501 ==地址0x0没有堆叠,malloc'd或(最近)免费

我尝试了注释/取消注释方法,一切正常,直到我使用atof ....我不明白因为它与小矩阵工作正常

大矩阵中的值如下所示:0.11991517其中,在小测试矩阵中,我只有0或0.1的值

我希望我解释得足够......请在需要时提出更多细节。

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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]," ,-");