我在C ++中使用gsl库。我已经将gsl_vector指针网格声明为该类的私有成员。
private:
gsl_vector * mesh;
我还有一个方法,MeshBuilder,声明一个gsl_vector,指针网格(覆盖原始网格变量)并返回网格。
gsl_vector * ThinFilm::LinearMesh(...){
gsl_vector * mesh = gsl_vector_alloc(numberofcells);
...
return mesh;
}
然后我将方法的结果分配给变量mesh:
mesh = MeshBuilder(...);
它编译并运行得很好(没有警告,使用-Wall)。单步执行该程序,我注意到变量网格被分配了一个地址,然后MeshBuilder会覆盖它。这正是我编程要做的。
但这是好的做法吗?毕竟,我不应该为指针地址赋值吗?
我不应该在MeshBuilder方法中声明网格指针,因此直接使用在类的私有部分中声明的指针吗?
我猜测这个工作的唯一原因是因为我分配给网格的地址值实际上已经被声明了。
答案 0 :(得分:3)
方法中的网格变量会隐藏私有变量。 如果您直接使用私有变量,那么您可以避免声明临时变量,但实际上,它并没有太大变化。
但是,如果要在多线程上下文中使用该类的接口,那么直接更改私有变量将使其在分配时的任何其他线程都可见,因此如果{{上面代码中的1}}部分对向量进行了某种设置,这意味着其他线程可能会看到或使用无效(未构造)变量。
在这种情况下,您应该使用临时(如在初始代码中)并使用互斥锁或原子操作(如CAS或指针交换)保护赋值...
。
此外,在所有情况下,如果您想编写安全代码,您还应该考虑将在代码的mesh = MeshBuilder(...)
部分抛出异常。
直接设置私有变量,您可能有机会清除分配(在类的析构函数中),否则您将获得内存泄漏,因为指针不会自行清除分配。
如果您想要一个在所有可能条件下都能正常工作的安全代码,您应该使用智能指针代替临时(用于异常安全代码),一个互斥锁来保护私有变量访问(对于多线程安全代码)。
答案 1 :(得分:2)
简单的答案是否定的,在您当前的代码中,您正在泄漏资源。
问题是gsl_vector_alloc
没有返回一个值,而是一个地址,它指向一个包含你要看的值的结构。在这种情况下,gsl_vector_alloc
的行为类似于使用new
,因为它分配了一个向量结构,并对其进行了初始化。
函数gsl_vector_alloc
,顾名思义就是分配一个向量。这意味着您需要在覆盖它之前使用gsl_vector_free
释放它。
分配也可能失败,在这种情况下,gsl_vector_alloc
将返回NULL
,您必须在使用网格之前检查它。
旁注:在你提供的函数中,你调用你的局部变量mesh,它与私有成员同名,这是一个不好的做法,因为局部变量会隐藏私有成员。