2016-05-31 5 views
0

Я хочу создать динамический массив 2d в отдельной функции. Размер массива будет определен во время выполнения.Функция, которая динамически создает 2d-массив

Передайте массив непосредственно:

void foo(int **arr,int width,int height) 
     { 
     arr=new int*[width]; 
     for(int i=0;i<height;i++) 
     { 
     arr[i]=new int[height]; 
     } 
     //fill... 
     } 
    ... 
    int** array; 
    foo(array) 

не похоже на работу

Передайте массив через указатель

void foo(int ***arr,int width,int height) 
     { 
     *arr=new int*[width]; 
     for(int i=0;i<height;i++) 
     { 
     *arr[i]=new int[height]; 
     } 
     //fill... 
     } 
    ... 
    int **array; 
    foo(&array) 

не кажется, работают либо

Как Я делаю это?

+1

Использовать 'std :: vector', больше нечего сказать. –

+1

Пожалуйста, избегайте этого и используйте 'std :: vector >'. Вам нужно передать тройной указатель, чтобы это работало. – 101010

+1

Если вы собираетесь пройти этот маршрут, вы можете сделать это [немного более оптимальным] (http://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in- c/21944048 # 21944048) – PaulMcKenzie

ответ

1

Предположим, что вам необходимо создать 2d массивы таким образом (с int**).

Вместо того чтобы пытаться передать указатели, верните значение, обозначающее 2d-массив.

Во-вторых, ваш код имел ошибку в том, что вы зацикливались на height, когда вы должны зацикливаться на width. Ваш код попал бы в неопределенное поведение, если height > width.

В-третьих, я не знаю, если вы имели в виду width быть первым измерение или height быть первым измерение, так что давайте предположим, что вы написали, что вы имели в виду, то есть width это первый размер и height является внутренний размер.

int **foo(int width, int height) 
{ 
    int **arr = new int*[width]; 
    for(int i=0; i<width; i++) 
     arr[i]=new int[height]; 
    return arr; 
} 
//.... 
int width = 10, height = 10; 
int** array = foo(width, height); 

Тогда вы должны написать код, чтобы удалить выделенные данные:

for (int i = 0; i < width; ++i) 
    delete [] array [i]; 
delete [] array; 

Теперь Сказав выше, и выше, должны работать, более оптимальный вариант найден here, где данные представляют собой один непрерывный блок вместо отдельных выделенных блоков. Это уменьшает количество раз new[] и delete [].

+0

Благодарим вас за помощь. Все ответы, похоже, работают, но ваш даже лучше, чем я хотел достичь (1 параметр меньше, тот же эффект) – AlanKalane

2

Я думаю, что ваша "проблема" вызвана игнорируя operator precedence

Второй код размещен, кажется, ошибка на линии с:

*arr[i]=new int[height]; 

, который должен быть

(*arr)[i]=new int[height]; 

Кроме того, как указывалось в другом документе, работа с необработанными указатели иногда может быть довольно зло (как в вашем примере с Указатель на указатель на указатель), сырые указатели также может вызвать некоторые проблемы с утечек памяти, висячие указатели, и т.д.. Используйте что-то «более практичное», например, std::vector или некоторые другие STL-контейнеры.

(Примечание: Под термином «СТЛ», я имею в виду часть стандартной библиотеки, основанной на STL)

1

Вообще говоря, многомерные массивы не должны никогда, никогда не быть созданы, как это. Вы должны использовать один массив, завернутый в объект, который предоставляет доступ к строке, столбцу, таблице и т. Д., Используя функцию operator().

Вы должны также никогда, никогда не использовать сырые указатели (за исключением странных, смягчающих обстоятельств), который является, почему я использую std::vector класс STL для реализации кода.

class array_2d { 
public: 
    array_2d(size_t width, size_t height) : 
    width(width), 
    height(height), 
    _array(width * height) 
    {} 

    int & operator()(size_t x, size_t y) { 
     return _array[y * width + x]; 
    } 

    const int & operator()(size_t x, size_t y) const { 
     return _array[y * width + x]; 
    } 

    std::pair<size_t, size_t> get_size() const { 
     return std::make_pair<size_t, size_t>(width, height); 
    } 
private: 
    size_t width, height; 
    std::vector<int> _array; 
}; 

int main() { 
    array_2d my_array(5,5); 
    my_array(3,3) = 7; 
    std::cout << my_array(3,3) << std::endl; 
    return 0; 
} 

====

7 

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

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