Diskuze: Dynamické pole pointrů na struktury
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 11 zpráv z 11.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
mozna uz v poradku...pred tim jsem mel novy typ struktury definovany v .c souboru a po presunuti definice do hlavickoveho souboru zadna chyba.
Deklarace typu i alokace dynamického pole ukazatelů na strukturu je v pořádku. Chybu máš v jiné části programu.
V následujícím programu je alokováno 10ti prvkové pole ukazatelů na strukturu, každému ukazateli je přiřazena tatáž adresa a nakonec proveden výpis struktury pomocí ukazatelů na strukturu uložených v dynamicky alokovaném poli.
#include <stdio.h>
#include <stdlib.h>
#define MAX_POLOZEK 10
typedef struct {
char znacka[11];
char velikost[4];
char typ[11];
int cena;
} TYP;
int main(void) {
TYP zbozi = { "NIKE", "L", "T-Shirt", 590 };
TYP** p_polozka_cislo = NULL;
p_polozka_cislo = (TYP**)malloc(MAX_POLOZEK * sizeof(TYP*));
if (!p_polozka_cislo) {
fprintf(stderr, "Chyba alokace pameti.\n");
exit(1);
}
for (int i = 0; i < MAX_POLOZEK; i++) p_polozka_cislo[i] = &zbozi;
for (int i = 0; i < MAX_POLOZEK; i++) {
printf("index %d: ", i);
printf("%s, ", p_polozka_cislo[i]->znacka);
printf("%s, ", p_polozka_cislo[i]->velikost);
printf("%s, ", p_polozka_cislo[i]->typ);
printf("%d\n", p_polozka_cislo[i]->cena);
}
free(p_polozka_cislo);
p_polozka_cislo = NULL;
return 0;
}
ty jsi vytvoril strukturu v hlavnim souboru.c a ve funkci main jsi potom
vytvoril pole a alokoval pro nej pamet coz mi taky funguje.
ja jsem v "hlavnim_souboru.c", kde je i funkce main nic z tohoto kodu
nemel.
vyvoril jsem soubor "pole.c a v nem bez jakekoli funkce jsem napsal kus kodu
vyse a to se mi nechtelo prelozit a navic jsem potreboval novy typ struktury
sdilet.
Tak jsem vytvoril halvickovy souboru "definice.h" kam jsem dal vsechny typedef a
definovane promene a funguje mi to.
jen porad nevim proc byl problem definovat pole pointru v jinem modulu a take v
nem alokovat dynamicky pamet
ted jsem zkusil nekolikrat kus kodu:
TYP **p_polozka_cislo = NULL;
p_polozka_cislo = (TYP **) malloc(MAX_POLOZEK * (sizeof(TYP *)));
vlozit kamkoli mimo funkci main a vzdy preklad selhal
uz to vidim ten pointer mohu definovat mimo funkci, jako jine promenne, ale alokaci pameti musim zavolat ve funkci jinak chyba
Deklarace nových typů se zapisují do hlavičkových souborů. Deklaraci lze v programu zapsat opakovaně, definici pouze jednou. Vložením hlavičkového souboru do zdrojového souboru poskytujeme informaci o typu, který se nachází v hlavičkovém souboru. Proměnná deklarovaná uvnitř funkce je viditelná pouze v této funkci. Proměnná deklarovaná vně funkce je viditelná všem funkcím v daném souboru. Pokud chceme rozšířit viditelnost globální proměnné, pak je třeba v souboru, ve kterém ji chceme zpřístupnit, používat extern. Ač deklarace proměnné i volání funkce malloc() jsou v obojím případě příkazy, musí být funkce malloc() volána uvnitř nějaké funkce. Proměnné lze deklarovat uvnitř nebo vně funkce.
prosím Vás,
příkazem
free(&p_polozka_cislo[0]); // sizeof ma 8B - nemohu pouzit protoze promenna pointer na pointer, který ukazuje na strukturu - je staticky definovan
free(p_polozka_cislo[0]); // sizeof ma 8B - uvolním část alokované paměti pro jeden pointer na strukturu
free(*p_polozka_cislo[0]); // sizeof má 26B - uvolním část alokované paměti a to na pro jednu strukturu
takze kdyz budu chtit vymazat kterykoli i-ty prvek(strukturu), tak zadam
free(*p_polozka_cislo[i]);
p_polozka_cislo[i] = NULL;
a v pripade potreby mohu znovu alokovat pamet, proto novy prvek(strukturu) a priradit mu adresu
p_polozka_cislo[i] = alokuj_pamet();
mota se mi to a nevim jestli tomu rozumim
oprava take nemohu pouzit - musm priradit hodnotu NULL
free(p_polozka_cislo[0]);
Takto to nefunguje. Nelze uvolnit pouze část alokované paměti z celého alokovaného bloku. Uvolnit lze pouze celou alokovanou paměť naráz, žádnou nebo realokovat stávající, což by ale v případě mazání jednoho záznamu bylo dosti neefektivní. Řeší se to tzv. dvojí alokací. První alokace udává to, na čem se bude stavět (dynamicky alokované pole, spojový seznam, či jiná datová struktura), druhá alokace udává objekt, na který se chceme odkazovat (v našem případě dynamicky alokovaná struktura). Ukazatele na takto dynamicky alokované struktury se přiřadí ukazatelům dynamicky alokovaného pole. Pak mohu vytvářet a odebírat jednotlivé objekty dle potřeby.
V níže uvedeném programu ukazuji výše popsanou techniku. Vytvářím tam nové záznamy a ukazatele na ně si uchovávám v poli. Nakonec všechny záznamy zruším, stejně tak jako zruším pole s ukazately na tyto záznamy. Lze samozřejmě vytvořit méně záznamů, kam je uložíme si rovněž lze určit. Pokud bych nevyužil celé pole pro záznamy, bylo by nutné nejprve všechny ukazatele nastavit na NULL. Tak lze poznat, který ukazatel v sobě udržuje adresu objektu a který ne a tedy se kterým ukazatelem lze pracovat a který blok paměti uvolňovat.
#include <stdio.h>
#include <stdlib.h>
#define MAX_POLOZEK 10
typedef struct {
char znacka[11];
char velikost[4];
char typ[11];
int cena;
} TYP;
int main(void) {
TYP** p_polozka_cislo = NULL;
// alokace pole ukazatelu na strukturu
p_polozka_cislo = (TYP**)malloc(MAX_POLOZEK * sizeof(TYP*));
if (!p_polozka_cislo) exit(1);
// alokace struktur a prirazeni zacatku pridelene pameti ukazatelum
for (int i = 0; i < MAX_POLOZEK; i++) {
p_polozka_cislo[i] = (TYP*)malloc(sizeof(TYP));
if (!p_polozka_cislo[i]) exit(1);
}
// Zde prace se strukturami
// ...
// uvolneni pameti vsech alokovanych struktur
for (int i = 0; i < MAX_POLOZEK; i++) {
free(p_polozka_cislo[i]);
p_polozka_cislo[i] = NULL;
}
// uvolneni pameti alokovaneho pole ukazatelu na strukturu
free(p_polozka_cislo);
p_polozka_cislo = NULL;
return 0;
}
Zobrazeno 11 zpráv z 11.