当我尝试填充数组时,我收到“Segmentation fault”。所以我想到在类中声明数组大小来声明数组的大小,以便它可以分配空间,但我收到了。
错误:无效使用非静态数据成员'Array :: Size'错误:来自 这个位置
//Current
class Array{
public:
int Size;
int Range;
int Array[];
};
//Problematic
class Array{
public:
int Size;
int Range;
int Array[Size];
};
还是有其他方法可以防止出现分段错误?
答案 0 :(得分:3)
您正在尝试使用C语言,其中结构的最后一个成员是一个非常短的数组(如果编译器允许作为非标准扩展,则为零元素),并为结构分配额外的内存因此可以访问声明数组末尾之外的元素。这最初是一种非标准技巧,称为struct hack,或者在某些编译器中称为zero-length arrays。它在C99中被标准化为flexible arrays。
当你使用这个习语时,你需要为数组分配额外的内存,例如: sizeof (struct Array) + sizeof (int) * number_of_elements
。否则你不会为你实际声明的元素分配更多的内存(通常是一个或零),当你试图访问超出它的元素时,你会得到未定义的行为。
但是,你在编写C ++,而不是C99。即使你的编译器允许你这样做,依赖它也是非常糟糕的做法,而且C语言比C语言更难。
将指针存储在类中并在构造函数中分配适当的内存量,并在析构函数中释放它,或者使用将为您管理内存的C ++类,例如: std::vector
。
以下是使用std::vector
:
#include <vector>
class Array{
public:
int size;
int range;
std::vector<int> array;
Array(int size, int range) :
size( size ),
range( range ),
array( size, 0 )
{
}
};
答案 1 :(得分:1)
这两个定义
//Current
class Array{
public:
int Size;
int Range;
int Array[];
};
//Problematic
class Array{
public:
int Size;
int Range;
int Array[Size];
};
无效。第一个是无效的,因为类定义可能不包含不完整的非静态数据成员。你可能不会写int array []; 第二个是无效的,因为1)数据成员大小具有未定义的值,2)数组的大小应该是常量表达式。 您可以使用指针并动态分配所需大小的数组,而不是声明数组。
答案 2 :(得分:0)
您可以使用指针。
class Array{
public:
int Size;
int Range;
int* Array;
};
在构造函数中,您可以为其分配内存。或者也许你可以在成员函数中完成它。
Array::Array(/*parameters*/){
/* code */
Array = new int [Size] //After Size is initialized or assigned.
}
在析构函数中,您应该使用delete[] Array
来释放内存。