Alokacja tablicy dwuwymiarowej w funkcji

0

Witam

Chciałbym napisać funkcję, która alokowałaby tablicę dwuwymiarową i aby ta tablica była dostępna w mainie. Próbowałem dwóch sposobów, jednak żaden z nich nie działa. Co prawda funkcja się wykonuje, jednak tablica nie jest dostępna w mainie.

Sposób pierwszy:

void alokuj(int ***tablica, int rozmiar1, int rozmiar2)
{
    tablica=new int**[rozmiar1];
    for(int i=0; i<rozmiar1; i++) tablica[rozmiar1]=new int*[rozmiar2];
}

i wywołanie w mainie:

 
int **mojatablica=NULL;
alokuj(&mojatablica, 10, 2);

Sposób 2:

int **alokuj(int rozmiar1, int rozmiar2)
{
    int **tablica;
    tablica=new int*[rozmiar1];
    for(int i=0; i<rozmiar1; i++) tablica[rozmiar1]=new int[rozmiar2];
    return(tablica);
}

i wywołanie w mainie:

 
int **mojatablica=alokuj(10, 2);

Będę wdzięczny za wszelkie wskazówki, jak to poprawić

Pozdrawiam

1
tablica[i] = new int... //blablabla
2

W obu przypadkach:

for(int i=0; i<rozmiar1; i++) tablica[rozmiar1]=new int[rozmiar2];

Powinno być tablica[i] = ...;
(w innym wypadku raz, że mażesz po niezaalokowanej pamięci, oraz dwa - inicjujesz cały czas ten sam element).

0

Dzięki

A pierwszy sposób jest w ogóle prawidłowy, bo po zmianie też mi nie działa (drugi oczywiście działa bez problemu :) )

1

Pierwszy nie poprawny, powinno być:

void alokuj(int ***tablica, int rozmiar1, int rozmiar2)
  {
   (*tablica)=new int*[rozmiar1];
   for(int i=0; i<rozmiar1;++i) (*tablica)[i]=new int[rozmiar2];
  }
1

Ewentualnie:

void alokuj(int **&tablica, int rozmiar1, int rozmiar2)
{
    tablica=new int*[rozmiar1];
    for(int i=0; i<rozmiar1; i++) tablica[i]=new int[rozmiar2];
}
0

Dziękuję za pomoc

Mam jeszcze jeden problem. Napisałem program do reprezentacji grafów za pomocą macierzy i listy sąsiedztwa> program kompiluje się, jednak gdy uruchomiam go (na komputerze z Windowsem) to otrzymuje komunikat This application has requested the Runtime to terminate it in an unusual way

Gdy program uruchamiam na ideone.com to otzrymuje komunikat:

 
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Jednak, gdy usunę z programu instrukcje i funkcje zwalniające pamięć to działa prawidłowo (na ideone, na komputerze nadal mam ten sam błąd).

Zwalniania pamięci wygląda u mnie tak:

 
zwolnij_pamiec(dane, n, 2);
zwolnij_pamiec(t_macierz, il_wierzch, il_wierzch);
delete [] t_list;

void zwolnij_pamiec(int **tablica, int rozmiar1, int rozmiar2)
{
    for(int i=0; i<rozmiar1; i++) delete [] tablica[i];
    delete [] tablica;
}
0

Próbowałem też zwalniania pamięci bez dodatkowej funkcji:

 
for(int i=0; i<rozmiar1; i++) delete [] mojatablica[i];
delete [] mojatablica;

jednak nadal występują te błędy.

0

Pokaż twoje aktualne przydzielenie pamięci, twoje aktualne zwolnienie pamięci, wywołanie przydzielenia i zwolnienia oraz wszystkie deklaracje związane z wywołaniem.

0

To cały kod programu:

 
#include<iostream>
using namespace std;
struct element_listy 
{
    int vertex;
    element_listy *next; 
    element_listy();
};
struct lista 
{
    element_listy *head;
    void dodaj(int vertex);
    void wypisz();
    lista(); 
};

int **alokuj(int rozmiar1, int rozmiar2);
int max(int a, int b);
void wczytaj_dane(int **tablica, int il_kr, int &il_wierzch);
void macierz(int **dane, int **t_macierz, int il_kr);
void lista_sasiedztwa(lista *t_list, int **t_macierz, int il_wierzch);
void wypisz_macierz(int **t_macierz, int rozmiar);
void wypisz_liste(lista *t_list, int rozmiar);
void graf();

int main()
{
    graf();
}
element_listy::element_listy()
{
    next=NULL;
}
lista::lista()
{
    head=NULL;
}
void lista::dodaj(int n_vertex) 
{
    element_listy *nowy=new element_listy;
    nowy->vertex=n_vertex;
    if(!head) head=nowy; else
    {
        element_listy *temp;
        temp=head;
        while(temp->next) temp=temp->next;
        temp->next=nowy;
        nowy->next=NULL;
    }
}
void lista::wypisz() 
{
    element_listy *temp;
    if(head)
    {
        cout << head->vertex << " ";
        temp=head->next;
        while(temp)
        {
            cout << temp->vertex << " ";
            temp=temp->next;
        }
    }
}
int **alokuj(int rozmiar1, int rozmiar2)
{
    int **tablica;
    tablica=new int*[rozmiar1];
    for(int i=0; i<rozmiar1; i++) tablica[i]=new int[rozmiar2];
    return(tablica);
}
int max(int a, int b)
{
    if(a>b) return a; else return b;
}
void wczytaj_dane(int **tablica, int il_kr, int &il_wierzch)
{
    for(int i=0; i<il_kr; i++)
    {
        cin >> tablica[i][0];
        cin >> tablica[i][1];
        il_wierzch=max(il_wierzch,max(tablica[i][0],tablica[i][1]));
    }
}
void macierz(int **dane, int **t_macierz, int il_kr) 
{
    for(int i=0; i<il_kr; i++)
    {
        t_macierz[dane[i][0]-1][dane[i][1]-1]=1;
        t_macierz[dane[i][1]-1][dane[i][0]-1]=1;
    }
}
void lista_sasiedztwa(lista *t_list, int **t_macierz, int il_wierzch) 
{
    for(int i1=0; i1<il_wierzch; i1++) for(int i2=0; i2<il_wierzch; i2++) if(t_macierz[i1][i2]==1) t_list[i1].dodaj(i2+1);
}
void wypisz_macierz(int **t_macierz, int rozmiar) 
{
    cout.width(3);
    cout << "    ";
    for(int i=0; i<rozmiar; i++)
    {
        cout.width(3);
        cout << i+1 << " ";
    }
    cout << "\n";
    for(int i1=0; i1<rozmiar; i1++)
    {
        cout.width(3);
        cout << i1+1 << " ";
        for(int i2=0; i2<rozmiar; i2++)
        {
            cout.width(3);
            cout << t_macierz[i1][i2] << " ";
        }
        cout << "\n";
    }
}
void wypisz_liste(lista *t_list, int rozmiar) 
{
    for(int i=0; i<rozmiar; i++)
    {
        cout << i+1 << " ";
        t_list[i].wypisz();
        cout << "\n";
    }
}
void zwolnij_pamiec(int **tablica, int rozmiar1, int rozmiar2)
{
    for(int i=0; i<rozmiar1; i++) delete [] tablica[i];
    delete [] tablica;
}
void graf()
{
    int n, il_wierzch;
    cin >> n;
    int **dane=alokuj(n,2);
    wczytaj_dane(dane, n, il_wierzch);
    int **t_macierz=alokuj(il_wierzch, il_wierzch);
    macierz(dane, t_macierz, n);
    lista *t_list=new lista[il_wierzch]; 
    lista_sasiedztwa(t_list, t_macierz, il_wierzch);
    cout << "Macierz:\n";
    wypisz_macierz(t_macierz, il_wierzch);
    cout << "\n\n\n";
    cout << "Lista sasiedztwa:\n";
    wypisz_liste(t_list, il_wierzch);
    //zwolnij_pamiec(dane, n, 2);
    //zwolnij_pamiec(t_macierz, il_wierzch, il_wierzch);
    for(int i=0; i< n; i++) delete[] dane[i]; delete [] dane;
    for(int i=0; i< il_wierzch; i++) delete[] t_macierz[i]; delete [] t_macierz;
    delete [] t_list;
}

0

Nie wiem czy ten błąd to wina funkcji zwalniających pamięć. Napisałem inny program, korzystający z tych samych funkcji alokujących/dealokujących i działa bez żadnych błędów.
Już sam nie wiem gdzie w tym kodzie jest błąd. Nie wygląda, żeby były tam jakieś wyjścia poza zakres tablic.

1

Jaka ma wartosc il_wierzch? Jednak pytanie trafne, patrzac na funkcje max.

0

Na wejście podawana jest ilość krawędzi oraz krawędzie w postaci par wierzchołków, oznaczonych liczbą (np. 2 8).
il_wierzch jest "największym" wierzchołkiem

A jeśli chodzi o wartość początkową to już jest poprawione na 0 :)

0

Dzięki
Dopiero teraz zauważyłem, że po zmianie wartości początkowej program już nie wywala błędu :)

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