Divné chování polí – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Divné chování polí – C / C++ – Fórum – Programujte.comDivné chování polí – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Seph
~ Anonymní uživatel
37 příspěvků
28. 11. 2013   #1
-
0
-

Nazdar,

střetl jsem se s něčím co opravdu nechápu. Problematiku polí jsem už dávno překonal a pro usnadnění jsem začal používat kontejnery. Ale co čert nechtěl, musím se hrabat v jednom ze svých starších kódů kde ještě pole používám. No, a to je ten problém. Oni ty kódy totiž nefungují (ale předtím fungovali ... aspoň myslím, já už teď fakt nevím nic jistě).  Problém popíšu přímo ve zdrojáku:

int foo(int ** bar, int width, int height)
{
    int result=0;
    for (int i=0;i<width;++i)
    {
        for (int y=0;y<height;++y)
        {
            result += bar[i][y];
        }
    }
    return result;
}

int main()
{
    using namespace std;
    int arr[3][3] =
    {
        {41,47,85},
        {96,78,14},
        {32,14,58}
    };
    /*Kompiler křičí že se nejedná o kompatibilní datové typy, ale co kecá OMG...arr JE 2D pole a to je skutečně pointer na pointer*/
    cout << foo(arr,3,3) << endl;
    /*Zde už kompiler nekřičí...ALE...program leze do paměti kam nemá a linux mi vyhodí SIGSEGV*/
    cout << foo((int**)arr,3,3) << endl;
    return 0;
}

Jakmile 2D pole dynamicky alokuju (přímo do ** ), žádné problémy nemám. Je to snad tím že C++ začalo brát staticky alokované pole jinak?? Dřív to nebylo ne? Jsem opravdu zmaten tímto problémem.

Nahlásit jako SPAM
IP: 80.188.252.–
Reklama
Reklama
KIIV+42
God of flame
28. 11. 2013   #2
-
0
-

nezacalo nic brat jinak... int ** predpoklada, ze druhy rozmer bude typu  int *

to ale dvojrozmerne pole nesplnuje - odpovida spis jen int * nez int** - vsechny cisla jsou v pameti hned za sebou a indexace se resi tak, ze kompilator proste vi, jakej je ten druhej rozmer, tak to prepocita

Pak kdyz udelas dereferenci prvniho rozmeru, tak tam nemas pointer na rozmer druhy, ale rovnou cislo

Nahlásit jako SPAM
IP: 94.113.94.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Seph
~ Anonymní uživatel
37 příspěvků
28. 11. 2013   #3
-
0
-

Takže to mám chápat tak, že u staticky alokovanejch polí kompilátor dělá optimalizaci v přístupu (2D pole je int * 2DArr ačkoli logika (a kniha) říká int ** 2DArr) a proto to prostě nepasuje ... fajn. Já mám prostě v podvědomí uloženo že to dřív fungovalo i s klasickym zápisem ... asi ne když říkáš. 

Nahlásit jako SPAM
IP: 80.188.252.–
Seph
~ Anonymní uživatel
37 příspěvků
28. 11. 2013   #4
-
0
-

Ať se snažím vzpomenout sebeurputněji, nemůžu si vzpomenout že by mi C++ (G++) něco takového v minulosti provedlo. Fakt mám pocit že tyto optimalizace přišli nedávno (rok zpět?). Na druhou stranu chápu výhodu tohoto řešení (vzhledem k tomu že staticky alokovaná pole jsou uložena na stacku).  

Nahlásit jako SPAM
IP: 80.188.252.–
KIIV+42
God of flame
28. 11. 2013   #5
-
0
-

to tvoje pole se prevede na:
{41,47,85, 96,78,14, 32,14,58}

a indexy se jen prepocitavaj podle toho druhyho rozmeru...  arr[x+y*3] by pak vyslo stejne jako arr[y][x] ...

Nahlásit jako SPAM
IP: 94.113.94.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Seph
~ Anonymní uživatel
37 příspěvků
28. 11. 2013   #6
-
0
-

Je to tak, děkuji za ochotu mi osvětlit tento problém.

Nahlásit jako SPAM
IP: 80.188.252.–
KIIV+42
God of flame
28. 11. 2013   #7
-
0
-

#6 Seph
coz u   int n=3; int ** arr = new int[n];  arr[0] = new int[n]; arr[1] = new int[n]; arr[2] = new int[n];

se uz nic jako  arr[x+n*y] pouzit neda .. zaprve by se to pokouselo ziskat pointer na adrese arr + x + n*y (kde uz zadnej pravdepodobne nebude), a hlavne to bude stale brano jako pointer

Nahlásit jako SPAM
IP: 94.113.94.–
Program vždy dělá to co naprogramujete, ne to co chcete...
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, 73 hostů

Podobná vlákna

Divné chování if-else — založil d.mostek

Fmod.. divne chovani?? — založil cp.Hook

Divné chování for cyklů — založil Blinder

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ý