赢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_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))
{}
};
您甚至可以更进一步,将
gsl_matrix
完全包装在更类似于C ++的界面中,并具有调用gsl_matrix_get
/ gsl_matrix_set
或gsl_matrix_pointer
的成员函数,以提供对矩阵元素的简单访问。关于c++ - 为什么"new"在类初始化中失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47822029/