为什么' new'类初始化失败

时间:2017-12-14 21:06:03

标签: c++

的win7 gcc 6.4.0 cygwin 2.9.0

以下代码在类初始化期间在函数g_block中失败,但在main中使用时则失败。失败发生在' for'当我尝试初始化代码时循环(初始化是这里的一个问题)。在这两种情况下,分配似乎都很成功,但在课堂上使用时,我无法使用分配的内存。

# include <iostream>
# include <iomanip>

using namespace std;

   typedef struct {                // gsl allocation 'block' descritpoin
      size_t size;                 // block bytes size
      double* data;                // pointer to the first byte of the block
   } gsl_block;

   typedef struct {                // matrix definition 
      size_t size1;                // number of rows
      size_t size2;                // number of columns
      size_t tda;                  // number of elements in row (stride between rows)
      double* data;                // pointer to matrix[0][0]
      gsl_block* block;            // pointer to the gsl_matrix block
      int owner;                   // 1: deallocation permitted
   } gsl_matrix;

class X {
public:
    inline static gsl_matrix& g_matrix(size_t row, size_t col) 
                         {return g_matrix(row, col, g_block(row * col));};

   static gsl_block&  g_block(size_t size)  {
      double* ptr = new double(size);
      cout << "size " << setw(5)<< size << " addr range " 
           << hex << setfill('0') << ptr << " - "  << (ptr + size*sizeof(double))
           << dec << setfill(' ') << endl;
      for(size_t ndx = 0; ndx < size; ndx++) ptr[ndx] = 0.0;
      return * new gsl_block{size, ptr};
   }; 

   static gsl_matrix& g_matrix(size_t row, size_t col, gsl_block& block) {
      return * new gsl_matrix{row, col, col, block.data, &block, 0}; }

   gsl_matrix& g_mat;
   X() : g_mat(g_matrix(92, 92)) {}
}; // class X
int main(int argc, char** argv) {
   gsl_matrix& mat = X::g_matrix(92, 92);
   X* x = new X();
   return 0;
}

1 个答案:

答案 0 :(得分:2)

double* ptr = new double(size);

此行在免费商店中创建一个值为double的{​​{1}},并返回指向它的指针。

size

然后,该行通过尝试写入程序不拥有的内存来调用未定义的行为。

您应该使用for(size_t ndx = 0; ndx < size; ndx++) ptr[ndx] = 0.0; 而不是原始指针。由于您的程序存在,您很有可能泄漏内存。如果您将std::vector设为gsl_block::data,那么您的课程将免费获得正确的副本和移动语义,您无需在代码中的任何位置直接使用std::vector<double>

编辑: 现在你已经提到过你正在使用GNU Scientific Library,你应该只使用库提供的函数来分配和释放matricies:newgsl_matrix_alloc。我会重新编写您的gsl_matrix_free课程,只包含X std::unique_ptr作为其删除者:

gsl_matrix_free

您甚至可以进一步完全将struct X { struct free_matrix { void operator()(gsl_matrix* mat) { gsl_matrix_free(mat); } }; std::unique_ptr<gsl_matrix, free_matrix> g_mat; X(std::size_t rows, std::size_t cols) : g_mat(gsl_matrix_alloc(rows, cols)) {} }; 包装在更像C ++的界面中,其成员函数可以调用gsl_matrix / gsl_matrix_getgsl_matrix_set来提供简单访问到矩阵元素。