2016-11-09 3 views
-2

Мне нужно создать матрицу с шириной и высотой, определяемую двумя параметрами, полученными из записи файла. Но в некоторых случаях, когда матрица слишком большая, у меня есть segmentation fault. Я думаю, вероятно, потому, что я создаю матрицу статическим способом, поэтому мне нужно создать ее динамически, но здесь, где возникает моя проблема, потому что я не знаю, как это сделать. Мой код прямо сейчас это:Создать массив динамически в C++

FILE * fp; 
    unsigned int width=0; 
    unsigned int height=0; 
    //Open the file. argv[4] parameter contains the file 
    fp=fopen (argv[4],"r"); 
    //Go to the last position which indicates the size 
    fseek(fp, 0, SEEK_END); 
    //Return to the start: 
    rewind(fp); 
    //The value of the first 4 bytes represent the width 
    size_t return1 = fread(&width,4,1,fp); 
    //The value of the next 4 bytes represent the height 
    size_t return2 = fread(&height,4,1,fp); 
//Matrix creation 
    if (return1 > 0 && return2 > 0) { 
    unsigned int matrix[width][height]; 
+0

Как вам удалось опубликовать свой код с помощью 'heigth' typo? В любом случае, начните: 1. Делайте вещи на C++, как это делается на C++ 2. с помощью Google – LogicStuff

+0

@LogicStuff Edited. Извините, это была ошибка ввода – giorgioW

ответ

4

Если у вас возникли проблемы, выяснить, как создавать массивы динамически, я бы определенно советую вам использовать vector класс вместо этого.

Векторы динамически распределяются и могут масштабироваться.

std::vector<unsigned int> matrix{width * height}; 

Обратите внимание, что я сделал вектор одним измерением, поскольку он очень упрощает выделение вектора.

Для доступа к конкретной координате можно использовать:

matrix.at(w * width + h); 

Где w и h координаты, h, очевидно, должно быть в диапазоне 0 <= h < height.

Если вы хотите динамически распределять свой массив, вам придется использовать оператор new, а затем необходимо помнить, чтобы очистить его, используя соответствующий оператор delete[]. Существует лучший ответ, что здесь на переполнение стека: How do I declare a 2d array in C++ using new?

В основном это свелось бы:

unsigned int** matrix = new unsigned int*[width]; 
for (int w = 0; w < width; ++w) { 
    matrix[w] = new unsigned int[height]; 
} 

Тогда вы должны помнить, чтобы удалить матрицу снова, используя что-то вроде этого:

for (int w = 0; w < width; ++w) { 
    delete [] matrix[w]; 
} 
delete [] matrix; 

Так, другими словами, я рекомендую вам использовать класс vector.

Конечно, при достаточно больших значениях ширины и высоты даже vector может потерпеть неудачу, просто потому, что вы пытаетесь выделить слишком много памяти. Если это так, я думаю, вы должны пересмотреть свой дизайн и пересмотреть, как это делается.

Не забудьте включить заголовок vector при использовании векторов:

#include <vector> 
+0

Использование векторов и компиляция, я получаю эту ошибку: 'terminate called после вызова экземпляра 'std :: out_of_range' what(): vector :: _ M_range_check: __n (что равно 1)> = this-> size() (что равно 1) ' – giorgioW

+0

@giorgioW Каков ваш вклад в функцию' at'? –

+0

Это ошибка выполнения, извините. Вход представляет собой вектор с размером 'width * height', называемым' matrixRed', следующим образом: 'matrixRed.at (i * width + j) = intr;' – giorgioW

2
unsigned int matrix[width][height]; 

Это имеет две проблемы.

Во-первых, width и height не являются константами времени компиляции, которые требуются стандарту C++ для размера массива. Поэтому ваша программа плохо сформирована. Ваш компилятор может поддерживать массивы переменной длины (VLA) в качестве расширения языка, поэтому он может работать с вашим компилятором в любом случае.

Во-вторых, VLA может храниться в стеке, а пространство стека ограничено. Действительно, с большим массивом вы можете легко переполнить стек. Вы правы, что вам нужно будет распределить массив динамически.И потому, что размер динамический (если вы хотите, чтобы ваша программа работала с другими стандартными компиляторами, которые не поддерживают VLA) и потому, что это предотвращает переполнение стека.

Самый простой способ создания динамического массива - std::vector. Томми Андерсен больше разбирается в том, как использовать векторы в своем ответе.