[C]Przydzielenie pamięci dla dynamicznej tablicy dwuwymiarowej

0

Mam napisac funkcje ktora umozliwi --> Przydzielenie pamięci dla dynamicznej, kwadratowej tablicy dwuwymiarowej (o wymiarze podanym jako parametr funkcji). Funkcja jako swoją wartość powinna zwracać wskaźnik do zaalokowanej tablicy.

Oto co stworzyłem, dopiero zaczynam z C wiec prosze o wyrozumiala pomoc. Gdy np chce zaaolokowac dla rozmiaru 2 czy tam 3 to naruszenie ochrony pamięci. Ogolnie to nie wiem gdzie tutaj są błędy i czy nie pisze tego w stylu na jaki nie przystalo dla C

 int przydziel (int *rozmiar)
 
{ 
  int (*tablica)[*rozmiar];
  tablica=(int(*)[*rozmiar]) malloc((*rozmiar)*(*rozmiar)*sizeof(int));  return tablica; }
 
int main (
  int *rozmiar;
  int *tablica; 
  printf("Podaj rozmiar tablicy  ");
  scanf("%d",rozmiar);
  przydziel(&rozmiar);
  free(tablica);}
0

Potrafie obslugiwac google, a po to wstawiam tu temat, bo napisalem cos co nie działa poprawnie i chcę wiedzieć dlaczego tak sie dzieje.

0

Napisałeś to kompletnie źle, ledwie to przypomina prawidłowe rozwiązanie. Dlatego odsyłamy do kursu/wykładu/książki.

1
  1. Nie utworzyłeś zmiennej na rozmiar tylko wskaźnik do takowej
  2. To się nie powinno skompilować nawet bo skoro rozmiar to wskaźnik to &rozmiar to wskaźnik do wskaźnika, a w funkcji oczekujesz na wskaźnik.
    Podsumowanie: nie rób jaj, tylko zrób tam zwykłą zmienną!
  3. Ta twoja deklaracja zmiennej "tablica" to jest jakieś OMG!WTF?! Przecież potrzebujesz tam tylko wskaźnik do inta i tyle!
  4. Reszta ok, pomijając rzutowanie na jakiś śmieszny typ.

Ale tak ogólnie to zrobiłeś to źle. Jeśli chcesz mieć faktycznie dwuwymiarową tablicę, taką do której można sie odnosić jak tablica[x][y] to musisz najpierw zaalokować tablicę wskaźników do wskaźników do int o rozmiarze "rozmiar", a potem dla każdego z tych wskaźników zaalokować tablicę intów o rozmiarze "rozmiar".

0
Shalom napisał(a):

Jeśli chcesz mieć faktycznie dwuwymiarową tablicę, taką do której można sie odnosić jak tablica[x][y] to musisz najpierw zaalokować tablicę wskaźników do wskaźników do int o rozmiarze "rozmiar", a potem dla każdego z tych wskaźników zaalokować tablicę intów o rozmiarze "rozmiar".
Nie do końca to prawda:

double **NewTb(unsigned N)
  {
   unsigned H=sizeof(double*)*N;
   char *buf=(char*)malloc(H+sizeof(double)*N*N);
   for(double **tmp=(double**)buf,**end=tmp+N,*tb=(double*)(buf+H);tmp<end;tb+=N) *(tmp++)=tb;
   return (double**)buf;
  }

Nie twierdzę że to dobre podejście (ma kilka wad) ale ma jedną zaletę: zwalniamy jednym free();

0

Stworzylem cos takiego, przypominam ze polecenie jest takie jak napisalem w pierwszym poscie.

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

int przydziel ( int *rozmiar){
  int wymiar;
  int i,j ;
  rozmiar=&wymiar;

  int (*tablica)[wymiar];

  tablica=(int(*)[wymiar]) malloc((wymiar)*(wymiar)*sizeof(int));
  for (i = 0; i < *rozmiar; i++)
    for (j = 0; j < *rozmiar; j++)
      tablica[i][j] = 10*i+j;
  return (*tablica)[wymiar];
}


int main (){
  int rozmiar;
  
  printf("Podaj rozmiar tablicy  ");
  scanf("%d",&rozmiar);
  printf("Rozmiar wynosi %d ",rozmiar);
  przydziel(&rozmiar);
}
  
  

Jesli chodzi o ten fragment ponizej :

int (*tablica)[wymiar];
 
  tablica=(int(*)[wymiar]) malloc((wymiar)*(wymiar)*sizeof(int)); 

To wiem ze byc moze istnieja inne lepsze sposoby , ale wykladowca dal nam tą metode jako jedyna uznawaną. Mysle ze jest ok, funkcja zwraca wskaznik do tej tablicy wypelnionej liczbami , co nie ?Chcialbym jednak wypelnic jej elementy z poziomu innej , nowej funkcji. Jako jej parametry mam podaj m.in. wskaznik do zaalokowanej wlasnie tablicy . Jak to ma wyglądac ? W sensie piszę definicje tej funkcji int wypelnij(*rozmiar, [?]......) help

0
misiek123 napisał(a):

... ale wykladowca dal nam tą metode jako jedyna uznawaną ...
Bzdury pleciesz, to co stworzyłeś to jakiś zlepek instrukcji cześć których nie może się skompilować niezależnie od deklaracji ich części. To wszystko nie ma najmniejszego sensu. W tym co podajesz są jakieś resztki poprawnego przydzielania tablicy jednowymiarowej, może o tym mówił wykładowca, na pewno o tym twoim kodzie będzie miał takie samo zdanie (lub podobne) co moje.

0

Poprawilem to, ale jest problem. Otoż chcialbym wypelnic jej elementy odpowiednimi wartosciami z poziomu zewnetrznej funkcji przydziel. No i wywala mi naruszenie ochrony pamieci. Domyslam sie ze zle przekazuje jako 2-gi argument wskaznik do tej tablicy

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

int **tab;


int przydziel ( int *rozmiar){
  int n = *rozmiar;
  int i,j;   
  
tab = (int**) malloc(n * sizeof(int*));

for(i = 0; i < n; i++)
    tab[i] = (int*) malloc(sizeof(int) * n);
  
 if(*tab==NULL)
    printf("Blad przydzielenia pamieci !");

  return **tab;
}





int wypelnij (int *rozmiar, int **tab){
  int i,j;

for(i = 0; i < *rozmiar; i++)
      for(j = 0; j < *rozmiar; j++)
	tab[i][j]=i*j;
}
   


int main (){
  int rozmiar;
 

  printf("Podaj rozmiar tablicy  ");
  scanf("%d",&rozmiar);
  printf("Rozmiar wynosi %d ",rozmiar);
  przydziel(&rozmiar);
  printf("teraz nast\n");
  wypelnij(&rozmiar,**tab);
   


 	       
}
  
0

Przecież kompilator ci wyraźnie pokazuje gdzie jest źle i co jest źle.

0
a.c:32:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
a.c:45:21: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'int **'
      [-Wint-conversion]
  wypelnij(&rozmiar,**tab);
                    ^~~~~
a.c:26:35: note: passing argument to parameter 'tab' here
int wypelnij (int *rozmiar, int **tab){
                                  ^
2 warnings generated.

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