赢7
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;
}

最佳答案

double* ptr = new double(size);


该行在免费存储中创建一个值为double的单个size,并返回指向它的指针。

for(size_t ndx = 0; ndx < size; ndx++) ptr[ndx] = 0.0;


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

您应该真正使用std::vector而不是原始指针。就您的程序而言,您很有可能泄漏内存。如果将gsl_block::data设置为std::vector<double>,则类将免费获得适当的复制和移动语义,并且您无需在代码中的任何位置直接使用new

编辑:
既然已经提到您正在使用GNU科学库,则可能应该只使用库提供的用于分配和释放矩阵的函数:gsl_matrix_allocgsl_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))
    {}
};


您甚至可以更进一步,将gsl_matrix完全包装在更类似于C ++的界面中,并具有调用gsl_matrix_get / gsl_matrix_setgsl_matrix_pointer的成员函数,以提供对矩阵元素的简单访问。

关于c++ - 为什么"new"在类初始化中失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47822029/

10-10 18:30
查看更多