2013-11-29 3 views
0

Я получаю «Ошибка сегментации» при попытке заполнить мой массив. Поэтому я подумал об объявлении размера массивов в классе, чтобы объявить размер массива, чтобы он мог выделить пространство, но я получаю.Объявление размера массива объекта в классе

error: invalid use of non-static data member ‘Array::Size’ error: from this location

//Current 
class Array{ 
    public: 
    int Size; 
    int Range; 
    int Array[]; 
}; 


//Problematic 
class Array{ 
    public: 
    int Size; 
    int Range; 
    int Array[Size]; 
}; 

или есть любой другой способ предотвращения ошибки сегментации?

ответ

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) 
     { 
     } 
}; 
+0

@Constantin Нет, 'int Array [];' недействительный способ объявить 'int *'. Ваш код, похоже, не компилируется для меня. См. [Здесь] (http://ideone.com/YmvpYc). – svk

+0

+1 Ты был прав: Ничего. – Constantin

+0

Это называется «гибкий массив» на C99. «Нуль-длина» будет чем-то вроде 'int a [0]', который никогда не был стандартным и доступен только как расширение для некоторых компиляторов. –

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) размер массива должен быть постоянным выражением. Вместо объявления массива вы можете использовать указатель и динамически выделять массив требуемого размера.

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 чтобы освободить память.

Смежные вопросы