• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Wskaźnik na tablice struktur

0 głosów
110 wizyt
pytanie zadane 4 maja w C i C++ przez inny_sub Użytkownik (760 p.)
zamknięte 4 maja przez inny_sub

Cześć, mam funkcję 

int fun(struct xyz **ptr);

I chcę teraz w tej funkcji zaalokować pamięć na 3 struktury xyz i zapisac adres tej tablicy do ptr. W skrócie robię to tak:

ptr = (struct xyz **)malloc(sizeof(struct xyz *) * 3);
for(int i = 0; i< 3; i++){ 
  struct xyz p;
  p.min = min
  *(ptr+ i) = &p;
}

Jednak coś tu nie działą i nie wiem co :(

 

komentarz zamknięcia: problem rozwiązany; *ptr= malloc(3* sizeof **ptr);

2 odpowiedzi

+1 głos
odpowiedź 4 maja przez RafalS VIP (115,340 p.)
wybrane 4 maja przez inny_sub
 
Najlepsza

Niepotrzebnie alokujesz tablicę wskaźników na struktury. Powinieneś zaalokować tablice struktur.

A tak dla edukacji:

for(int i = 0; i< 3; i++){ 
  struct xyz p;
  p.min = min
  *(ptr+ i) = &p;
}

W każdym obiegu pętli tworzysz obiekt xyz i zapamiętujesz jego adres. Tylko, że te obiekty przestają istnieć po każdorazowym wyjściu z ciała pętli. Klasyczny błąd trzymania wskaźnika do zwolnionego obiektu:

int* fun() {
    int x=10;
    return &x;
}

int main() {
    int *ptr = fun();
    *ptr = 5; // odwołanie do zwolnionego obiektu, undefined behaviour, przeważnie crash
}

A Twój kod powinien wyglądać tak:

	struct xyz* ptr = (struct xyz *)malloc(sizeof(struct xyz ) * 3);
	for (int i = 0; i < 3; i++) {
		ptr[i].min = min;
	}

 

komentarz 4 maja przez inny_sub Użytkownik (760 p.)

Dzięki za treściwą odpowiedź, jednak definicja funkcji musi pozostać niezmieniona, czyli musi wyglądac następująco:

int fun(struct xyz **ptr);

Tak, abym po wyjsciu z funkcji mógł odwoływać się do struktur w taki sposób:

(ptr+1)->pole

Poprawiłem kod na taki:

#include <stdio.h>
#include <stdlib.h>
struct xyz{
  int min;
};

int fun(struct xyz **ptr){
  *ptr= (struct xyz*)malloc(sizeof(struct xyz) * 3);
  for(int i = 0; i< 3; i++){
    (*(ptr+ i))->min = 3;
  }
  return 0;
}

int main(){
  struct xyz *p;
  fun(&p);
  printf("%d", (p+1)->min);
  return 0;
}

Jednak mimo to jest cos prawdopodobnie z alokacja.

+1 głos
odpowiedź 4 maja przez DeBos123 Nałogowiec (36,490 p.)
Problem jest w tym, że alokujesz miejsce na wskaźniki, a nie na same obiekty.

Rozmiar twojej struktury to 4 bajty, a wskaźnika 8 bajty (lub 4 bajty na 32-bitowym systemie).

Ty alokujesz 8*3=24;

Potrzebujesz (8*3)+(4*3)=24+12=36;

8+4=12, czyli masz miejsce tylko na 2 struktury i wskaźniki, przy 3 naruszasz pamięć.
komentarz 4 maja przez inny_sub Użytkownik (760 p.)
To fakt.. W takim razie w jaki sposób dodatkowo alokować miejsce na obiekty struktur?
komentarz 4 maja przez DeBos123 Nałogowiec (36,490 p.)

W taki sposób alokujesz miejsce dla wszystkich wskaźników:

malloc(sizeof(struct xyz*)*3);

Później dla każdego wskaźnika musisz zaalokować miejsce dla struktury na którą wskazuje:

malloc(sizeof(struct xyz));

 

komentarz 4 maja przez inny_sub Użytkownik (760 p.)

Okej, to pomogło, a jeszcze jedna kwestia. Funkcja fun(int ***ptr);

Chcę teraz zaalokować pamięć na tablicę wskaźników (10 elementow) i tablice (2 elementowa) na które dany wskaźnik wskazuje.

*ptr = malloc(10 * sizeof(int *));
 for(int i =0 ; i< 10; i++){
      *(*ptr+i) = (int *)calloc(2, sizeof(int));
      *(*(*ptr+i)+1) = 2555;
    }

 

I znów coś jest nie tak. Chyba nie do końca rozumiem dereferencje, jeśli ktoś ma jakiś dobry poradnik do tego to poproszę o podesłanie :)

komentarz 4 maja przez DeBos123 Nałogowiec (36,490 p.)
Nie do końca rozumiem co chcesz osiągnąć. Chcesz mieć tablicę z dziesięcioma wskaźnikami i każdy z nich wskazuje na 2-elementową tablicę?
komentarz 4 maja przez inny_sub Użytkownik (760 p.)
Dokładnie tak :)
komentarz 4 maja przez DeBos123 Nałogowiec (36,490 p.)

W takim razie sama zmienna wygląda tak:

int** ptr=malloc(sizeof(int*)*10);

int** oznacza wskaźnik na wskaźnik na int'a.

int* to jest wskaźnik na int'a, który może być pierwszym elementem tablicy wtedy 'wskazuje' on na tablicę, czyli int** to 'tablica tablic'.

Int* zajmuje 8 bajtów (4 na 32-bitowych systemach, ale ja będę działał w przykładzie na 64-bitowym), czyli jeżeli 8*10=80, to zarezerwowałeś miejsce dla 10 wskaźników.

Następnie w pętli rezerwujesz miejsce dla 2 wskaźników, które będą tworzyć tablicę:

for(int i=0;i<10;++i){
    ptr[i]=malloc(sizeof(int*)*2);
}

Później zostało jeszcze zarezerwować miejsce dla każdego int'a, na który wskazują każde 2 wskaźniki, czyli możesz dodać do pętli:

for(int j=0;j<2;++j){
    ptr[i][j]=malloc(sizeof(int));
}

czyli finalnie pętla wygląda tak:

for(int i=0;i<10;++i){
    ptr[i]=malloc(sizeof(int*)*2);
    for(int j=0;j<2;++j){
        ptr[i][j]=malloc(sizeof(int));
    }
}

Jeżeli masz jakieś pytania, bądź potrzebujesz objaśnienia jakiegoś to pisz.

Podobne pytania

0 głosów
1 odpowiedź 56 wizyt
0 głosów
1 odpowiedź 639 wizyt
pytanie zadane 3 października 2017 w C i C++ przez Huberti Gaduła (3,570 p.)
0 głosów
2 odpowiedzi 233 wizyt
pytanie zadane 3 lipca 2018 w C i C++ przez qlucha Obywatel (1,790 p.)
Porady nie od parady
Forum posiada swój własny serwer Discord, dzięki któremu będziesz mógł po prostu pogadać z innymi Pasjonatami lub zapytać o jakiś problem. Podstrona z chatem znajduje się w menu pod ikoną człowieka w dymku.IRC

67,017 zapytań

113,930 odpowiedzi

241,411 komentarzy

46,960 pasjonatów

Przeglądających: 135
Pasjonatów: 5 Gości: 130

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...