2009-12-20 3 views
3

У меня есть segmentationfault на линии: cout < < b [0] [0];Как вернуть массив размера 2 в C++

Кто-нибудь может сказать мне, что я должен сделать, чтобы исправить мой код?

#include <iostream> 
using namespace std; 

int** gettab(int tab[][2]){ 
    return (int**)tab; 
} 

int main() { 
    int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}}; 
    int ** b = gettab(a); 
    cout << b[0][0]; 
    return 0; 
} 

ответ

5

2-мерный массив не то же самое, как массив указателей, который, как int** интерпретируется. Измените тип возврата gettab.

int* gettab(int tab[][2]){ 
    return &tab[0][0]; 
} 

int main() { 
    int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}}; 
    int* b = gettab(a); 
    cout << b[0]; // b[row_index * num_cols + col_index] 
    cout << b[1 * 2 + 0]; // the 1 from {1, 0} 
} 

Или:

int (*gettab(int tab[][2]))[2] { 
    return tab; 
} 
// or: 
template<class T> struct identity { typedef T type; }; 
identity<int(*)[2]>::type gettab(int tab[][2]) { 
    return tab; 
} 

int main() { 
    int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}}; 
    int (*b)[2] = gettab(a); 
    cout << b[0][0]; 
} 
+0

Если вы собираетесь использовать нижний предел, оставьте комментарий, чтобы сказать почему. – 2009-12-20 21:58:39

+0

Эта строка: int (*) [2] gettab2 (int tab [] [2]) { не компилируется. У меня есть ошибка: main.cpp | 14 | ошибка: ожидаемый неквалифицированный идентификатор до ')' токен | main.cpp | 14 | ошибка: ожидаемый инициализатор перед 'gettab2' | – user56642

+0

Должно быть Int (* gettab (вкладка ИНТ [] [2])) [2] Я рекомендую не возвращающие массивы, хотя :) – DanDan

1

Ваш сегментный вина нас, потому что вы передаете в "междунар *" эффективно. 2D-массив не является двойной стрелкой ...

Лучше всего использовать указатель размером «x * y» и адресовать его без двух измерений ... код будет таким же, как и в любом случае компилятор будет генерировать тот же код, который вам нужно будет писать в явном виде :)

3

Быть C++, а не c, Есть muchbetter способы обработки массивов всех видов и их передачи.

+0

+1 Я хочу, чтобы все знали это :) –

+0

еще одна хорошая ссылка: http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.11 «Почему моя матрица не должна интерфейс класса выглядит как массив-массив? " – danio

+0

@danio, но интерфейс моего матричного класса выглядит так, oh no D: – James

0

a 2 diminsional array - это не то же самое, что массив указателей. 2 одномерный массив является просто указателем на ломоть памяти, что вы сказали компилятору, чтобы получить доступ как 2 одномерный массив

int* gettab(int tab[][2]) { 
    return (int*)tab; 
} 

int main() { 
    int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}}; 
    int* b = gettab(a); 
    cout << b[0 + 2*0]; 
    return 0; 
} 

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

редактирование: исправлено отсутствие * 2 в расчете [0 + (sizeof (int) * 2) * 0]. Еще раз редактировалось: ну что было немым. в этом случае умножение размера столбца на 2 по размеру int. sizeof (int) удален.

+0

Что именно 'sizeof (int)' делает в 'b [0 + sizeof (int) * 0]'? – avakar

+0

просто глупая ошибка. –

2

Тип tab без квадратных скобок на самом деле не int **. Фактически это int (*)[2]. Когда вы применяете два оператора [] к результирующему указателю, вы в конечном итоге разыгрываете первое значение в своем массиве 0 в качестве указателя NULL. Попробуйте это вместо этого:

#include <iostream> 
using namespace std; 

typedef int (*foo)[2]; 

foo gettab(int tab[][2]){ 
    return tab; 
} 

int main() { 
    int a[4][2] = {{0, 0}, {1, 0}, {2, 0}, {2, 1}}; 
    foo b = gettab(a); 
    cout << b[0][0]; 
    return 0; 
}