Dynamicka alokace pameti pole – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Dynamicka alokace pameti pole – C / C++ – Fórum – Programujte.comDynamicka alokace pameti pole – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
jmeno
~ Anonymní uživatel
27 příspěvků
20. 12. 2014   #1
-
0
-

 Dobrý den potřebuju vytvořit dynamicky pole o určité velikosti a když přestane stačit tak zkopírovat obsah do druhého pole  , smazat malé pole a vytvořit znovu pole o X násobek větší ,kde vrátím ty hodnoty z druhého pole

int main()
{
    int static cislo = 0;
    while(cislo < 50)
    {


    int static pole = 15;

    int * zaznam = new int[pole];

    if(pole == cislo)
    {
    int *zaznam2 = new int[pole*2]; // alokovat nove ople o potrebne velikosti

    memcpy(zaznam2, zaznam, sizeof(int)*(pole/2)); // zkopirovat

    delete [] zaznam; // smazat stare

    zaznam = zaznam2; // pole bude ukazovat na nove aloovanz blok pameti
    }
    zaznam[cislo] = cislo;
    cout << zaznam[cislo] << endl;
    cislo++;
    }
}

tento kód nefunguje úplně chtěl bych poprosit o opravu, děkuji.

Nahlásit jako SPAM
IP: 94.113.229.–
Reklama
Reklama
q
~ Anonymní uživatel
219 příspěvků
21. 12. 2014   #2
-
0
-

Ten 'zaznam' se ti vytváří při každém průchodu. Vyhoď to ven a nepoužívej static, když to nepotřebuješ.

A mezi tou alokací nového pole a kopírováním jsi asi chtěl uložit novou velikost.

Doporučuji logičtější názvy proměnných a nešetřit klávesnici a raději všechno primitivně rozepsat.

int velikost = 15;
int * pole = new int[velikost];

for (int cislo = 0; cislo < 50; ++cislo)
{
	if (cislo == velikost)
	{
		int novavelikost = velikost * 2;
		int * novepole = new int[novavelikost];

		memcpy(novepole, pole, sizeof(int) * velikost);

		delete[] pole;

		pole = novepole;
		velikost = novavelikost;
	}

	pole[cislo] = cislo;
}
Nahlásit jako SPAM
IP: 213.211.51.–
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #3
-
0
-

#2 q
děkuju za pomoc chtěl bych se ještě zeptat jak to zakombinuju do loopu a se strukturou, myslel jsem ze to zvladnu uz sam ale nejak mi to nejde

toto jsem vytvořil

a když chci vypsat pole po minimálně jednom přeplnění tak se vypíšou jenom 0,

Nahlásit jako SPAM
IP: 94.113.229.–
q
~ Anonymní uživatel
219 příspěvků
21. 12. 2014   #4
-
0
-

Nerozumím, ukaž.

Nahlásit jako SPAM
IP: 213.211.51.–
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #5
-
0
-

#4 q
minutku ja jsem to napsal ono se to neuložilo

Nahlásit jako SPAM
IP: 94.113.229.–
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #6
-
0
-

   

struct struktura
{
	int ID;
	string jmeno;
};

int id = 0;
while(menu != 0)
{
        struktura * pole = new struktura[velikost];
        if (id == velikost)
        {
            novavelikost = velikost * 2;
            struktura*novepole = new struktura[novavelikost];

            memcpy(novepole, pole, sizeof(akt) * velikost);

            delete[] pole;

            pole = novepole;
            velikost = novavelikost;
        }

	cin >> menu;

        switch(menu)
        {
        case 0: break;
        case 1: plneni pole po jednom prvku ...
		cin >> pole[id].ID >> pole[id].jmeno;
		id++;
		break;
	case 2: plneni pole ze souboru (ifstream) ...
		while(getline(...))
		{
		plneni pole[id] ...

                    if (id == velikost)
                    {
                        akt * pole = new akt[velikost];
                        novavelikost = velikost * 2;
                        akt *novepole = new akt[novavelikost];

                        memcpy(novepole, pole, sizeof(int) * velikost);

                        delete[] pole;

                        pole = novepole;
                        velikost = novavelikost;
                    }
		id++
		}
		break;
	case 3: vypis pole
		for(int i = 0; i < id; i++) cout << pole[i].ID << ' ' << pole[i].jmeno << endl;
break;
Nahlásit jako SPAM
IP: 94.113.229.–
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #7
-
0
-

A když se pole jednou zvětší ztratím všechny hodnoty a vypisuje to jenom 0 0 .

Nahlásit jako SPAM
IP: 94.113.229.–
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #8
-
0
-

#7 jmeno
místo akt tam má být struktura

Nahlásit jako SPAM
IP: 94.113.229.–
ingiraxo+15
Grafoman
21. 12. 2014   #9
-
0
-

#8 jmeno
řešíš to špatně, zbytečně alokuješ úplně nový pole a kopíruješ data, pro tyhle účely slouží realloc 

struct Bagr
{
    int num;
    Bagr(int num) : num(num) {}
};

int main()
{
    int size = 0;
    Bagr* arr = NULL;

    for (int i = 0; i < 10; i++) {
        arr = (Bagr *) realloc(arr, ++size * sizeof(Bagr));
        *(arr + size - 1) = Bagr(i);
    }
    delete[] arr;
    return EXIT_SUCCESS;
}
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #10
-
0
-

Bohužel musím použít metodu s dvoumi poli, tak jestli by jste mi mohli pomoct upravit ten můj kód.

Nahlásit jako SPAM
IP: 94.113.229.–
KIIV+42
God of flame
21. 12. 2014   #11
-
0
-

#9 ingiraxo
pouziva tam string, takze jede v c++ a definitivne neni dobry michat malloc s new a tak.. natoz new s realloc...

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ingiraxo+15
Grafoman
21. 12. 2014   #12
-
0
-

#11 KIIV
proč míchat? jediný co tam alokuje je to pole, takže žádný new tam použít nemusí, stačí jeden realloc jak jsem uvedl

ale je to jedno, stejně píše že má použít 2 pole a kopírovat data, takže klidně použít new

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
KIIV+42
God of flame
21. 12. 2014   #13
-
0
-

#12 ingiraxo
problem prvni: std::string se neda tak snadno zkopirovat pomoci memcpy (jak udela delete [], zavola se destruktor)

problem druhy: beztak ma ten new na zacatku cyklu, tak se nemuze divit, ze prichazi o data

bonus: pole v c++ alokovane pomoci new[] ma dokonce extra informaci i velikosti pole (aby se mohly pri delete[] zavolat destruktory, jakozto opak konstruktoru pro new[])

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ingiraxo+15
Grafoman
21. 12. 2014   #14
-
0
-

#13 KIIV
aha toho stringu jsem si nevšim, je pravda, že u realloc nevim jak se to přesně zachová u objektů z stl, pro dealokaci je tam free a on nejspíš nevolá destruktory u stl objektů

k tomu bonusu... takže teoreticky když se naalokuje třeba přes calloc pole stl objektů a zavolá se pak delete[], tak se nezavolají desktruktory, protože alokace neobsahuje informaci o velikosti pole?

#10 jmeno
 

// 2 parametry pro pole je zbytecny, pokud chces mit 2, tak tam pridej
// vstup a vystup, ale vzhledem k tomu, ze se jedna jen o pomocny pole,
// tak je druhej parametr pole na nic
template<typename T>
void realloc(T*& arr, int& size, int inc = 1)
{
    T* tmp = new T[size + inc];
    copy(arr, arr + size, tmp);
    delete[] arr;
    arr = tmp;
    size += inc;
}

// uprava toho co jsem psal
for (int i = 0; i < 10; i++) {
    realloc(arr, size);
    *(arr + size - 1) = Bagr(i);
}
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #15
-
0
-

Mohli by jste mi prosím vás poradit jak překopíruju ty pole mezi sebou klidně i přes for nemusí to být přes memcpy. kod je pořád stejný jako v 6tém příspěvku celkem to spěcha. děkuju

Nahlásit jako SPAM
IP: 94.113.229.–
ondrej39+1
Věrný člen
21. 12. 2014   #16
-
0
-

#15 jmeno
Normálně máš iterátor i a pokud máš dvě pole, původní a dvojnásobně velké, tak v rámci for cyklu udeláš dvojnasobne_pole[i] = puvodni_pole[i];, pak už je jen třeba správně vyřešit podmínku aby se z for cyklu vyskočilo, když se dojde na poslední prvek původního pole. Vymyslet vhodně break; by neměl pro tebe být problém.

Nahlásit jako SPAM
IP: 176.74.132.–
Inject all the dependencies!
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #17
-
0
-

To je mi jasné, ale já mám ze začátku jedno pole o velikosti X, a když mi přestane stačit tak potřebuju vytvořit nové o 2*X, a smaza to stare, a takhle pořád dokola. Překopírování pole je mi +- jasné, ale nevím jak vytvořit to druhé pole aby nahradilo to první a používalo se jenom to dokud zase nepřestane stačit.

Nahlásit jako SPAM
IP: 94.113.229.–
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #18
-
0
-

   

 while(loop)

{

      akt * pole = new akt[velikost];
        if (id == velikost)
        {
            novavelikost = velikost * 2;
            akt *novepole = new akt[novavelikost];

            for(int i = 0; i < velikost; i++)
            {
                novepole[i].ID = pole[i].ID;
                novepole[i].cislo1= pole[i].cislo1;
                novepole[i].cislo2= pole[i].cislo2;
                novepole[i].cislo3= pole[i].cislo3;
                novepole[i].string1= pole[i].string1;
                novepole[i].cislo4= pole[i].cislo4;
                novepole[i].cislo5= pole[i].cislo5;
            }

            delete[] pole;

            pole = novepole;
            velikost = novavelikost;
        }

}

Mám to takle je to v loopu, a problém asi bude že se mi to pole vytvoří znova nebo tak něco.

když to chci vypsat po vytvořeni novehopole tak se vypíšou akorát nuly, potřebuju toto upravit tak aby to fungovalo.

Nahlásit jako SPAM
IP: 94.113.229.–
KIIV+42
God of flame
21. 12. 2014   #19
-
0
-

problem je v tom, ze mas deklaraci akt * pole UVNITR cyklu... ho v KAZDYM KOLE VYTVORIS, zvetsis a ZAPOMENES (resp. zapomenes, kde je, v pameti zustane)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
jmeno
~ Anonymní uživatel
27 příspěvků
21. 12. 2014   #20
-
0
-

Děkuju moc už mi to funguje :)

Nahlásit jako SPAM
IP: 94.113.229.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 86 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý