Proste zwracanie tablicy dwuwymiarowej

0

Witam, mam prosty problem którego nie mogę rozwiązać. Chcę zwrócić tablicę dwuwymiarową, z jednowymiarową nie mam problemu ale już z dwu tak, próbowałem najróżniejszych sposobów, co jest źle?

#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

int ** moo()
{
	int t[2][2];
	 t[0][0] = 22;
	 t[0][1] = 12;
	 t[1][0] = 10;
	 t[1][1] = 11;
	
	return &t[0][0]; //tu tez na rozne sposoby probowalem
}

int main()
{
    
	int ** b[2][2]; // probowalem tez bez tych [2][2]
	
	b = moo();
	cout<<b[0][0]<<" "<<b[1][0];
    return 0;
}
0

A musisz zwracać? Nie możesz przekazać wskaźnika do funkcji i niech ona sobie to wypełnia? W tym momencie tworzysz dwie tablice w pamięci, przy czym jedna z nich jest niszczona po zakończeniu działania funkcji. Podejrzewam, że nie o to Ci chodzi. Jeśli koniecznie chcesz zwracać, to alokuj tablicę w funkcji dynamicznie i zwracaj wskaźnik po wypełnieniu jej danymi. W ten sposób dane nie zostaną zdealokowane po wyjściu z niej.

0

Chcę po prostu w funkcji stworzyć tablicę, do której zwrócę wskaźnik, wystarczy jedna tablica. Chcę ją móc używać poza funkcją

0

To musisz ją stworzyć dynamicznie operatorem new na stercie. Nie możesz jej stworzyć na stosie, bo zaraz po wyjściu z funkcji pójdzie w diabły.

0

No ok, tego nie wiedziałem. Myślę że potrafiłbym ją stworzyć dynamicznie, ale jak już mam taką tablicę stworzoną dynamicznie tab to jak ją zwrócić (tzn. chyba ten wskaźnik tylko do niej wystarczy)

0

Nie ma innej możliwości. Alokacja dynamiczna sprawi, że po wyjściu z funkcji te dane w pamięci pozostaną i będą nadal zaalokowane. Musisz jakoś poinformować wyższy poziom logiczny o tym, gdzie te dane w pamięci leżą i robisz to poprzez wskaźnik. Pamiętaj tylko o zwolnieniu tej pamięci kiedy dane nie będą już potrzebne. Jeśli funkcja jest wywoływana często, lepiej jest jednak zaalokować pamięć wyżej i powiedzieć funkcji po którym miejscu w pamięci może bazgrać. Unikniesz tym samym niepotrzebnych alokacji i dealokacji, które mogą być dość kosztowne.

0

Ta funkcja będzie wykonywana raz na obieg programu, tzn może być wykonywana kilka razy, ale tak jak napisałeś wcześniej będzie ta tablica usuwana. To ok, teoretycznie wiem jak to zrobić i rozumiem zasadę działania, ale jak zwrócić wskaźnik na tablicę dwuwymiarową a potem go odczytać poza funkcją? Chodzi mi o tę zabawę gwiazdkami, czy mam zwracać coś takiego

return &tab[0][0]; //wskaznik na 1 (czy aby na pewno?) element
//czy
return tab; //wskaznik niby na pierwszy element w tablicy jednowymiarowej ale czy w dwu tez?

No i jak jest z tym odbieraniem poza funkcją?

0

Niestety, nie wiem jak to jest w C++, ale w C przy tablicy alokowanej dynamicznie masz tylko indeksy jednowymiarowe, gdyż alokujesz po prostu blok pamięci. Możesz sobie zaalokować statycznie matrycę o wymaganych wymiarach, a potem nadpisać pamięć przez nią zajmowaną danymi z pamięci tablicy dynamicznej (memcpy), ale nie wiem czy warto marnować pamięć i cykle tylko po to, aby móc się później odwoływać do komórek poprzez indeksy. Uwaga! C++ może mieć jakieś mechanizmy, które to umożliwią. Z pewnością spece od tego języka się tu wypowiedzą w takim przypadku.
Nieco chaotyczny przykład z dynamiczną alokacją pamięci w funkcji:

#include <stdio.h>
#include <stdlib.h>


int  *fun(int  rows, int  cols)
{
    int     *tab, row, col;


    if ( (tab = (int*)calloc(cols * rows, sizeof(int))) == NULL )
        return NULL;

    for ( row = 0; row < rows; row++ )
        for ( col = 0; col < cols; col++ )
            tab[row * cols + col] = 10 * (row + 1) + col;

    return tab;
}



int  main(void)
{
    int     *data, row, col;


    if ( (data = fun(5, 2)) == NULL ) {
        perror("fun()");
        return 1;
    };

    for ( row = 0; row < 5; row++ )
        for ( col = 0; col < 2; col++ )
            printf("%d\n", data[row * 2 + col]);

    free(data);
    return 0;
}
0

#include <iostream>

using namespace std;

int** foo(int size)
{
    int** tab = new int*[size];
    for(int i = 0; i < size; i++)
        tab[i] = new int[size];
    return tab;
}

int main()
{
    int n = 10;
    int** t = foo(n);
    
    //operacje na tablicy
    
    for(int i = 0; i < n; i++)
        delete[] t[i];
    delete[] t;
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1