2013-04-09 2 views
2

Я хочу использовать двумерный массив int, который возвращается из функции , как определить значение возвращаемой функции? я использовал Int ** но компилятор дает ошибку:возвращение двухмерного массива из функции в C++

int** tableCreator(){ 
    int** table=new int[10][10]; 
    for(int xxx=1;xxx<10;xxx++){ 
     for(int yyy=1;yyy<10;yyy++){ 
      table[xxx][yyy]=xxx*yyy; 
     } 
    } 
    return(table); //Here:cannot convert from 'int (*)[10]' to 'int **' 
} 

ответ

4
int** table=new int[10][10]; 

это неправильно. вы не можете выделить пространство для 2D динамического массива таким образом в C/C++.

Между тем, вы объявили размер массива, как 10, поэтому индексы из 0-9, но вы пытаетесь присвоить значение индекса 10 в вашем вложенном для петель, которые не является правильным тоже.

Вы можете сделать следующее для выделения:

int** table = new int*[10]; 
for (int i = 0; i < 10; ++i) 
{ 
    table[i] = new int[10]; 
} 
+1

Если размеры известны во время компиляции, вы можете выделить пространство для двумерного массива таким образом. То есть, распределение 'new int [10] [10]' является правильным. Объявление таблицы должно быть изменено. Если массив прямоугольный (не имеет строк разной длины), то выделение нескольких указателей и использование указателей для указателей является расточительным. Выделение по-прежнему может выполняться одним вызовом, а несколько измерений могут поддерживаться с помощью вспомогательного класса или других конструкций. –

+0

Кроме того, создание указателей на указатели вызывает поиск нескольких указателей всякий раз, когда используется таблица, и это мешает компилятору оптимизировать код. Когда есть указатели на указатели, компилятору может быть сложно определить, что они на самом деле указывают на разные вещи и поэтому не могут друг друга. Когда таблица передается как указатель на один объект, компилятор знает, что ссылки на разные индексы - это разные места в памяти. Это позволяет переупорядочить код, что может улучшить время выполнения. –

0

I. Массивы не являются указателями.

II. Почему не vector<vector<int> >?

III. Если нет, то:

typedef int Int10Array[10]; 
Int10Array *arr = new Int10Array[10]; 

IV. Зачем писать за гранью? Вам нужны явные носовые демоны?

for(int xxx = 0; xxx < 10; xxx++) 
      ^^^  ^^^^ 
5

Попробуйте это:

#include <cstdio> 
#include <cstdlib> 


int** createTable(int rows, int columns){ 
    int** table = new int*[rows]; 
    for(int i = 0; i < rows; i++) { 
     table[i] = new int[columns]; 
     for(int j = 0; j < columns; j++){ table[i][j] = (i+j); }// sample set value;  
    } 
    return table; 
} 
void freeTable(int** table, int rows){ 
    if(table){ 
     for(int i = 0; i < rows; i++){ if(table[i]){ delete[] table[i]; } } 
     delete[] table;  
    } 
} 
void printTable(int** table, int rows, int columns){ 
    for(int i = 0; i < rows; i++){ 
     for(int j = 0; j < columns; j++){ 
      printf("(%d,%d) -> %d\n", i, j, table[i][j]); 
     }  
    } 
} 
int main(int argc, char** argv){ 
    int** table = createTable(10, 10); 
    printTable(table, 10, 10); 
    freeTable(table, 10); 
    return 0; 
} 

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

Уточнение в соответствии с беседой с @Eric Postpischil ниже: изменилось createTable, чтобы подсчитать количество строк/столбцов для действительно динамического распределения.

+0

Заявление «Вам нужны две петли, чтобы выделить 2-й массив в C и аналогичную операцию, чтобы освободить его». False. Многомерные массивы с фиксированными размерами во всех, кроме самого внешнего размера, легко выделяются одним «новым» и освобождаются одним «удалением», а использование нескольких вызовов «новый» и «удаление» является расточительным. Массивы переменной длины могут поддерживаться различными способами, которые не требуют множественных распределений и освобождений. –

+0

, но это необходимо, только если вы выделяете строки фиксированной длины. например Х [10] [10]. Если ваши строки имеют переменную длину, настоящий массив массивов, вам нужны петли. – mohaps

+0

.. и посмотрим на принятый ответ :) он делает цикл. если вы динамически распределяете, например. allocate2DArray (int i, int j), вам нужно зацикливать, не так ли? – mohaps

1

Обычно тип, указывающий на массив, является указателем на элемент массива. Поскольку двумерный массив из int представляет собой массив из массива int, вы хотите указать указатель на массив из int. Синтаксис C++ для этого типа: int (*)[N], для некоторого измерения N. Этот код демонстрирует:

#define N 10 

int (*tableCreator())[N] 
{ 
    int (*table)[N] = new int[N][N]; 

    for (int i = 0; i < N; ++i) 
     for (int j = 0; j < N; ++j) 
      table[i][j] = i*j; 

    return table; 
} 


#include <iostream> 


int main() 
{ 
    int (*t)[N] = tableCreator(); 

    for (int i = 0; i < N; ++i) 
    { 
     for (int j = 0; j < N; ++j) 
      std::cout << t[i][j] << ' '; 
     std::cout << '\n'; 
    } 

    delete [] t; 

    return 0; 
} 
Смежные вопросы