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

realloc() dla struktury

Object Storage Arubacloud
–1 głos
1,062 wizyt
pytanie zadane 22 marca 2017 w C i C++ przez Evelek Nałogowiec (28,960 p.)
edycja 22 marca 2017 przez Evelek

Mam taki kod:

#include <stdio.h>
#include <stdlib.h>
static size_t rozmiar_tablicy = 1;

typedef struct vector {
	int tab[];
} Vector;

void AlokujPamiec(struct vector *wsk) {
	wsk = malloc(sizeof(int));
	rozmiar_tablicy++;
}

void DodajElement(struct vector *wsk, int wartosc) {
	wsk = realloc(wsk, sizeof(wsk) + sizeof(int));
}

int main(void)
{	
	Vector tablica;
	AlokujPamiec(&tablica);
	DodajElement(&tablica, 5);

	return 0;
}

Co nie napiszę, to mi wyrzuca wyjątek w podświetlonym wierszu nr 15. Funkcja realloc() przyjmuje jako argumenty wskaźnik do miejsca w pamięci, gdzie pamięć ma być ponownie przydzielona oraz rozmiar. Jak to można poprawić? EDIT: Teraz tak mi przyszło do glowy po wyłączeniu laptopa, ale nie mam jak sprawdzić, może tak to trzeba napisać: wsk = realloc(&wsk, sizeof(wsk) + sizeof(int));

2 odpowiedzi

0 głosów
odpowiedź 22 marca 2017 przez adrian17 Ekspert (344,860 p.)
wybrane 22 marca 2017 przez Evelek
 
Najlepsza

Zakładając że to C, to robisz wiele rzeczy bez sensu.

wsk = malloc(sizeof(int));

Alokujesz cały obiekt, a zgaduję że chodziło Ci o to, żeby tab był wskaźnikiem.

realloc(wsk, sizeof(wsk) + sizeof(int));

sizeof(wsk) nie robi tego co myślisz - to tylko daje rozmiar samego wskaźnika.

Ogólny minimalny poprawny kod wyglądałby tak:

#include <stdlib.h>

struct vector {
    int *tab;
};

int main(void)
{   
    struct vector tablica;
    tablica.tab = malloc(sizeof(int));
    tablica.tab = realloc(tablica.tab, sizeof(int) * 2);
    free(tablica.tab);
    return 0;
}

(downvote'ującego proszę o komentarz)

komentarz 22 marca 2017 przez Evelek Nałogowiec (28,960 p.)
edycja 22 marca 2017 przez Evelek

Alokujesz cały obiekt, a zgaduję że chodziło Ci o to, żeby tab był wskaźnikiem.

 Nie. Chciałem dla całej struktury.zaalokować pamięć, a wskaźnik mieć do całej struktury.

Evelek: realloc(wsk, sizeof(wsk) + sizeof(int));

Adrian17: sizeof(wsk) nie robi tego co myślisz - to tylko daje rozmiar samego wskaźnika.

I tu chyba mam błąd właśnie...Myślałem, że zwiększa on pamięć struktury i że wskaźnik jest tu tylko pośrednikiem. Dzięki za działający przykład, idę pisać dalej.

 

EDIT: Przecież wskaźnik wsk ma rozmiar struktury? Przekazuje strukturę:

DodajElement(&tablica, 5);

A wskaźnik wsk jest tą strukturą:

void DodajElement(struct vector *wsk, int wartosc)

Czyli używam oryginalnej struktury, nie żadnej kopii.

komentarz 22 marca 2017 przez Evelek Nałogowiec (28,960 p.)
Jak coś to edit komentarz, bo nie wiem czy Ci się wyświetla.
–1 głos
odpowiedź 22 marca 2017 przez degrek Bywalec (2,380 p.)

 błąd: invalid conversion from 'void*' to 'vector*' [-fpermissive]
     wsk = malloc(sizeof(int));

Mi osobiście wyrzuca dwa razy ten sam błąd: linia 10 i 15.

Nie wiem czy dobrze rozumiesz funkcje malloc i realloc, zwracają one wskaźniki do nowo utworzonych tablic. A teraz spróbujmy przeanalizować Twój kod:
jako argumenty funkcji masz wskaźnik na strukturę, i do niego próbujesz przypisać wartość zwracaną przez funkcję malloc/realloc, a powinieneś to wskaźnika tablicy. Chodzi oto, że nie odwołujesz się do nigdzie do swojej tablicy, którą masz w strukturze.

Moje rozwiązanie:

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

static size_t rozmiar_tablicy = 1;

struct vector
{
    int *tab;
};

void alokujPamiec(struct vector vtr)
{
    vtr.tab = (int*) malloc(sizeof(int));
}

void dodajElement(struct vector vtr, int ilosc_elemntow) {
    vtr.tab = (int*)realloc(vtr.tab, (rozmiar_tablicy + ilosc_elemntow) * sizeof(int));
    rozmiar_tablicy += ilosc_elemntow;
}

int main()
{
    vector myVector;
    alokujPamiec(myVector);
    dodajElement(myVector,5);
    return 0;
}

 

komentarz 22 marca 2017 przez adrian17 Ekspert (344,860 p.)

błąd: invalid conversion from 'void*' to 'vector*' [-fpermissive] 
     wsk = malloc(sizeof(int));

Bo kompilujesz C++a, a nie C...

komentarz 22 marca 2017 przez Evelek Nałogowiec (28,960 p.)
  1. To jest C, a nie C++.
  2. Twój kod się nie kompiluje (użycie niezainicjowanej zmiennej lokalnej myVector).

Nie wiem czy dobrze rozumiesz funkcje malloc i realloc, zwracają one wskaźniki do nowo utworzonych tablic. A teraz spróbujmy przeanalizować Twój kod:
jako argumenty funkcji masz wskaźnik na strukturę, i do niego próbujesz przypisać wartość zwracaną przez funkcję malloc/realloc, a powinieneś to wskaźnika tablicy. Chodzi oto, że nie odwołujesz się do nigdzie do swojej tablicy, którą masz w strukturze.  

Jak to wskaźniki do nowo utworzonych tablic? Spójrzmy:

http://en.cppreference.com/w/c/memory/malloc --->  On success, returns the pointer to the beginning of newly allocated memory.

http://pl.cppreference.com/w/cpp/memory/c/malloc ---> Funkcja malloc() przydziela obszar pamięci o rozmiarze size i zwraca do niego wskaźnik.

I tak, alokuje pamięć dla CAŁEJ STRUKTURY a nie dla pojedynczej zmiennej. Czytałem, że można w ten sposób, więc z niego korzystam.

komentarz 22 marca 2017 przez Evelek Nałogowiec (28,960 p.)
Btw. Teraz doczytałem, że moja struktura jest w sumie niepoprawna, bo jeśli chcę korzystać z elastycznych składników tablicowych (C99), to struktura musi posiadać jeszcze jeden składnik.
komentarz 22 marca 2017 przez degrek Bywalec (2,380 p.)
Racja moje niedopatrzenie
komentarz 22 marca 2017 przez Evelek Nałogowiec (28,960 p.)

Ale i tak dzięki za przykład. smiley Btw.: Wolę przekazywać w tym przypadku strukturę przez wskaźnik niż przez wartość tak jak w Twoim kodzie, bo zawsze to szybciej będzie działać. wink (chociaż przy jednym składniku struktury różnice mogą być znikome, ale zawsze).

Podobne pytania

0 głosów
1 odpowiedź 143 wizyt
pytanie zadane 4 marca 2020 w C i C++ przez Programmingc100 Bywalec (2,620 p.)
0 głosów
3 odpowiedzi 586 wizyt
pytanie zadane 15 lutego 2018 w C i C++ przez kaka1997 Nowicjusz (190 p.)
0 głosów
1 odpowiedź 544 wizyt
pytanie zadane 26 stycznia w C i C++ przez TOWaD Mądrala (5,700 p.)

92,551 zapytań

141,393 odpowiedzi

319,523 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...