的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;
}
答案 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:new
和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))
{}
};
包装在更像C ++的界面中,其成员函数可以调用gsl_matrix
/ gsl_matrix_get
或gsl_matrix_set
来提供简单访问到矩阵元素。