C/C++ dynamická alokace paměti

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

Dominátor
nováček
Příspěvky: 3
Registrován: duben 19
Pohlaví: Nespecifikováno
Stav:
Offline

C/C++ dynamická alokace paměti

Příspěvekod Dominátor » 22 črc 2020 22:21

Zdravím,

potřeboval bych od Vás trochu objasnit problematiku týkající se dynamického (rostoucího) pole a s tím související dynamickou alokaci paměti - malloc, realloc, případně new v C++ apod. Jde o to, že ve všech návodech, videích apod je ten postup prakticky totožný ->

1. vytvořím si pole na haldě o nějaké velikosti např. int* heapArray = (int*) malloc(3 sizeof(*heapArray));
2. poté, až kapacita tohoto pole nebude dostačovat, tak se použije realloc (data zůstanou, velikost pole se zvětší - většinou např. 2x)
3. v C++ jelikož realloc není, tak se to buď řeší buď přímo zabudovaným vectorem a nebo vytvořením druhého většího pole a zkopírováním hodnot z prvního do tohoto nově vytvořeného pole.
4. to vše samozřejmě ideálně zakomponovat do nějaké struktury která bude obsahovat další proměnné, jako kapacita, velikost apod...

Dynamické pole jsem podle kódů z návodů pochopil, ale trochu jsem si s tím hrál a vůbec jsem nepobral pár věcí. Na tyto věci (celkově 2) se ptám přímo v komentářích v první části kódu kódu - příšlo mi to přehlednější, než to vypisovat sem.

první a druhá část je oddělena hvězdičkami

v druhé části jsem se bez nutnosti používat realloc nebo vytvoření druhého pole snažil vytvořit primitivní dynamicky rostoucí pole a zdá se, že vše funguje (žádný problém jsem nezaznamenal).

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

int main()
{
// alokace pole na haldě
int* heapArray = (int*) malloc(sizeof(*heapArray)); // nebo v C++ int* heapArray = new int;
heapArray[0] = 0; // *(heapArray) = 0;
heapArray[1] = 1; // *(heapArray + 1) = 1;
heapArray[2] = 2; // *(heapArray + 2) = 2;

//v pořádku
printf("%d ", heapArray[0]);
printf("%d ", heapArray[1]);
printf("%d \n", heapArray[2]);

printf("%p ", &heapArray[0]);
printf("%p ", &heapArray[1]);
printf("%p \n", &heapArray[2]);

//jakou hodnotu má dalších 7 políček a existují vůbec?
heapArray[10] = 500;

//pointerová aritmetika funguje
printf("%d ", *(heapArray+10));
printf("\n");

/*pokud funguje kód výše proč bych vůbec při alokaci pole měl udávat počet políček?
int* heapArray = (int*) malloc(pocet_policek * sizeof(*heapArray)); ? */

//*******************************************************************************//

int* heapArray2 = (int*) malloc(sizeof(*heapArray2));
int velikost_pole = 0;

printf("zadej pocatecni velikost pole: ");
scanf("%d", &velikost_pole);

//počáteční velikost
for(int x = 0; x < velikost_pole; x++){
heapArray2[x] = x;
}

for(int x = 0; x < velikost_pole; x++){
printf("%d ", heapArray2[x]);
}

printf("\n");

//rozšíření pole
for(int x = velikost_pole; x < velikost_pole*2; x++){
heapArray2[x] = x;
}

for(int x = velikost_pole; x < velikost_pole*2; x++){
printf("%d ", heapArray2[x]);
}

printf("\n");

//vypsání celého pole
for(int x = 0; x < velikost_pole*2; x++){
printf("%d ", heapArray2[x]);
}

free(heapArray2);

return 0;
}

Jelikož jsem na internetu nic podobného nenašel, tak jsem se rozhodl zeptat se zde vás.
Buď to funguje, protože to prostě fungovat může a není to spatně, a nebo je to totálně celé špatně, ale funguje to (vím, že tohle se u C/C++ stát může) :D.

Reklama
Uživatelský avatar
rhsCZ
Level 4
Level 4
Příspěvky: 1356
Registrován: červen 13
Bydliště: Jedna Velká díra ve středu Evropy :D
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: C/C++ dynamická alokace paměti

Příspěvekod rhsCZ » 23 črc 2020 00:51

u malloc se píše velikost, protože si rezervuje určitou velikost v paměti. jde o to, že když jsem vzal tvůj kód jak je(první a druhá část dohromady), tak mi malloc v druhé částí hodil exception, protože se snažil allokovat pamět, která neměla být allokovována prvním heapArray. Jakože jde o to, že by jsi s takhle psaným programem mohl narazit, že by jsi klidně mohl pokoušet přistupovat k paměti, kterou si allokoval jiný program. nebo by třeba jiný program také nemusel fungovat. prostě si allokuješ určitou část paměti a víš, že k ní máš behem běhu programu přístup. btw. ve vs2019 u int* heapArray = (int*)malloc(sizeof(*heapArray)); prý má range 0-0, allokovaná velikost na 1 hodnotu int.

Dodatečně přidáno po 28 vteřinách:
P.S. doufám, že jsem nenapsal nějakou kravinu


„Zeptáš-li se, budeš 5 minut vypadat jako blbec. Nezeptáš-li se, budeš blbcem po celý život.“
„Mnozí z těch, co žijí, by zasluhovali smrt. A mnozí z těch, co zemřeli, by si zasloužili žít.“ - John Ronald Reuel Tolkien
„Je lepší být nenáviděn pro to, jaký jsi, než být milován pro to, co nejsi.“ - Kurt Cobain
https://rhscz.eu
https://github.com/rhsCZ

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7359
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: C/C++ dynamická alokace paměti

Příspěvekod faraon » 23 črc 2020 01:30

Dokážeš vysvětlit, co přesně dělá tenhle řádek kódu?

Kód: Vybrat vše

int* heapArray = (int*) malloc(sizeof(*heapArray));
Kolik bajtů RAM sis tím vlastně alokoval?

Pokud to úplně přesně nevíš, zkus si tohle:

Kód: Vybrat vše

printf("%d\n", sizeof(*heapArray));
A také UTFM ;-)

Činnost se může lišit v různých operačních systémech. Jeden ze způsobů je, že ti správce paměti systému při prvním požadavku přidělí celou stránku paměti, a tu si potom rozděluje správce paměti programu. Takže ty si sice alokuješ jenom 4 bajty, ale ve skutečnosti máš povolený přístup třeba do celé stránky velké například 4 KiB.

U jednoprvkového pole tak zapíšeš možná i do array[1000] a nic se nestane, nebo si přepíšeš nějaká jiná data v úplně jiné proměnné, ale program běží dál. Teprve až když se pokusíš pracovat s odkazem mimo tvojí stránku, porušíš ochranu paměti a OS tvůj program nemilosrdně sestřelí na segfault.
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)

Dominátor
nováček
Příspěvky: 3
Registrován: duben 19
Pohlaví: Nespecifikováno
Stav:
Offline

Re: C/C++ dynamická alokace paměti

Příspěvekod Dominátor » 23 črc 2020 22:10

Děkuji všem za velmi poučné rady, které pomohly! :) nechtěl jsem se vrhat do něčeho dalšího, dokud aspoň částečně nepochopím tohle. Teď se můžu pustit do dalších pokusů.


  • Mohlo by vás zajímat
    Odpovědi
    Zobrazení
    Poslední příspěvek
  • Dynamická velikost tabulky
    od Funstorm007 » včera, 21:01 » v Kancelářské balíky
    0
    59
    od Funstorm007 Zobrazit poslední příspěvek
    včera, 21:01
  • Test pamětí Příloha(y)
    od Zakk » 14 čer 2023 20:12 » v Problémy s hardwarem
    6
    2433
    od Zakk Zobrazit poslední příspěvek
    19 čer 2023 21:35

Zpět na “Programování a tvorba webu”

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 4 hosti