Z komunikatu błędu wynika, że nazwa tablicy jest w tym przypadku tablicą wskaźników (na pierwsze elementy poszczególnych wierszy).
Wydaje mi się że jak zrobisz
Można traktować nazwę tablicy jako wskaźnik do pierwszego elementu, ale nie można traktować adresu dwuwymiarowej tablicy integerów jako wskaźnika na wskaźnik na integera.
... c-function
Statyczna dwuwymiarowa tablica to ciągły blok pamięci. Obrazowo: mając tablicę int array[m][n] dostęp do elementu array[i][j] polega na odczytaniu elementu *(array + i*m + j). array to wskaźnik na pierwszy element tablicy, a wskaźnik jest po prostu liczbą. Ponieważ tablica dwuwymiarowa ma umieszczone elementy w ciągłym bloku, możemy po prostu przesunąć się o i wierszy długości m, a następnie o j kolejnych elementów i voila — docieramy do pożądanego elementu. Należy tutaj zauważyć, że znamy długość wiersza tablicy!
Z tego też powodu tablica integerów i wskaźnik do integera nie jest tym samym (mimo że masa kursów w internecie tak twierdzi). Tablica integerów ma swój rozmiar, wskaźnik do integera wskazuje jedynie na liczbę. Fakt, że możemy to wykorzystać przy dostępie do wielu elementów nie sprawia, że jest to to samo. Jeszcze lepiej widać to przy obiektach, gdy przekazująć Base* nie wiemy, czy wskazujemy na obiekt klasy bazowej, na obiekt klasy dziedziczącej po Base, czy może na tablicę obiektów Base. W C++ nie ma żadnej magii, trzeba myśleć na każdym kroku.
Idąc dalej: tablica dwuwymiarowa alokowana dynamicznie (przy użyciu new bądź malloc) nie jest dwuwymiarową tablicą integerów, a jednowymiarową tablicą wskaźników na jednowymiarowe tablice integerów (obrazowo, szczegóły w standardzie języka). Mając int **array i odwołując się do elementu array[m][n] tak naprawdę odwołujemy się do elementu *(*(array + m) + n). Wewnętrzne nawiasy wyznaczają odwołanie się do m-tego wskaźnika do tablicy jednowymiarowej (a bardziej precyzyjnie: do m-tego wskaźnika do integera), który następnie przesuwamy o n i uzyskujemy pożądany element. Z tego względu przy przekazaniu tablicy dwuwymiarowej wylatujemy w powietrze, gdyż *(array + m) zawiera jakąś wartość (zwykły integer), która raczej nie jest poprawnym wskaźnikiem (czytaj: wskaźnikiem do naszej pamięci). Z tego powodu próba rzutowania tablicy dwuwymiarowej na wskaźnik do wskaźnika nie zadziała (spowoduje niepoprawny dostęp do pamięci przy wykonywaniu, skompiluje się za to bez problemu).
Z powyższej analizy wynika też, dlaczego można zmienić przyjmowany typ na coś w stylu (*int)[5] lub int [][5] — przy czymś takim znamy rozmiar tablicy, a to jest nam niezbędne przy próbie odwoływania się do drugiego wymiaru (gdyż musimy znać długość wiersza, a tej informacji nie mamy przekazując wskaźnik do wskaźnika).
W jaki sposób ? W przypadku przekazywania tablicy statycznej "normalnie" (czyli nie przez * i &) oraz jak sobie zaalokuję tablicę dynamiczną ,to przy wywołaniu funkcji podaje się nazwę tablicy (tutaj tab) i wszystko działa.Więc jak to zrobić z tablicą statyczną ?
BTW jarek4700, wtedy program wysypuje w kilu innych miejscach.