Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: ennyque 10. 04. 2013, 18:24:05

Název: Nejasnost v C++
Přispěvatel: ennyque 10. 04. 2013, 18:24:05
Dobrý den, chtěl bych Vás poprosit o radu. Když jsem se snažil v cpp vytvořit dynamicky matici, nakonec se mi nepodařilo zkompilovat nic jiného než:

Kód: [Vybrat]
int **prvky;

typedef int* uint;

prvky = new uint[dimx];

for ( int j = 0; j < dimy; j++)
{
   prvky[j] = new int[dimy];
}

Ale co jsem nepochopil, proč to nejde udělat bez typedef nového typu uint.

Nevíte prosím, jaký mechanismus, předpis, zabraňuje použití:  prvky= new (int*)[dimx];

děkuji za případnou radu.
Honza
Název: Re:nejasnost v C++
Přispěvatel: Jakub Galgonek 10. 04. 2013, 18:38:27
Nevíte prosím, jaký mechanismus, předpis, zabraňuje použití:  prvky= new (int*)[dimx];

Vadí mu ty závorky, zkus: prvky = new int*[dimx];

Mimochodem, v cyklu máš špatně podmínku.
Název: Re:nejasnost v C++
Přispěvatel: ennyque 10. 04. 2013, 18:45:27
Skutečně, děkuji.

Nevíte do hloubky, co Ty závorky způsobily, že to nešlo přeložit?

Honza
Název: Re:nejasnost v C++
Přispěvatel: Jakub Galgonek 10. 04. 2013, 19:08:09
Nevíte do hloubky, co Ty závorky způsobily, že to nešlo přeložit?

No, pravidla neumožňují sázet u definic typů závorky jen tak. Ale zase nějak extra hluboko do toho nevidím.
Název: Re:nejasnost v C++
Přispěvatel: ertwertwertwe 10. 04. 2013, 20:49:26
#include <stdio.h>
#include <stdlib.h>
#define DIMX 10
#define DIMY 20

int main()
{

//int **prvky = (int**) malloc (DIMX * sizeof (int*)); <-- takto je to v C
int **prvky = (int**) new int*[DIMX];
int i,j;


for (j = 0; j < DIMY; j++)
{
           //prvky[j] = (int*) malloc (DIMY * sizeof (int)); <-- takto je to v C
           prvky [j] = (int*) new int[DIMY];
}

for (i=0;i<DIMX;i++)
 for (j=0;j<DIMY;j++) {

         prvky[j] = i+j;
 }

for (i=0;i<DIMX;i++) {
 for (j=0;j<DIMY;j++)
         printf ("%d ",prvky[j]);
 printf ("\n");
 }

return 0;
}
Název: Re:Nejasnost v C++
Přispěvatel: DK 10. 04. 2013, 21:01:30
Citace
prvky [j] = (int*) new int[DIMY];
a ja blbec myslel, ze v c++ je to delane prave tak, aby se predeslo tomu zbytecnemu pretypovani  :-X no asi jsem se spletl :)
Název: Re:Nejasnost v C++
Přispěvatel: mchf 10. 04. 2013, 21:03:32
Nevíte do hloubky, co Ty závorky způsobily, že to nešlo přeložit?
Se zavorkama se to interpretuje jako "ukazatel typu int na pole" no a to nedava moc smysl.
Název: Re:Nejasnost v C++
Přispěvatel: xcvcdvsd 10. 04. 2013, 21:18:29
Citace
prvky [j] = (int*) new int[DIMY];
a ja blbec myslel, ze v c++ je to delane prave tak, aby se predeslo tomu zbytecnemu pretypovani  :-X no asi jsem se spletl :)

oprator new ma tuto definici:
void* operator new[]

taky vraci void* stejne jako malloc.
Název: Re:Nejasnost v C++
Přispěvatel: Jakub Galgonek 10. 04. 2013, 21:25:40
taky vraci void* stejne jako malloc.

Musím tě zklamat, ale nemáš pravdu.
Název: Re:Nejasnost v C++
Přispěvatel: xcvcdvsd 10. 04. 2013, 21:34:15
taky vraci void* stejne jako malloc.

Musím tě zklamat, ale nemáš pravdu.

japato???

void *malloc(size_t size);
http://linux.die.net/man/3/malloc

void* operator new (std::size_t size);
http://www.cplusplus.com/reference/new/operator%20new/
Název: Re:Nejasnost v C++
Přispěvatel: Jakub Galgonek 10. 04. 2013, 21:42:50
void* operator new (std::size_t size);
http://www.cplusplus.com/reference/new/operator%20new/

Vždyť tam také volají new bez přetypování :D. Ona hlavička operátoru new je jedna věc a hodnota výrazu new je věc druhá. Zkus si třeba přeložit tohle:

Kód: [Vybrat]
struct c {
    int x;
};

int main() {
    (new c)->x = 0;
}
Název: Re:Nejasnost v C++
Přispěvatel: j 10. 04. 2013, 21:47:21
Kód: [Vybrat]
int **prvky;

typedef int* uint;

prvky = new uint[dimx];

for ( int j = 0; j < dimy; j++)
{
   prvky[j] = new int[dimy];
}
Vykašli si na tyhle hrůzy s ruční alokací paměti a použij něco praktičtějšího a čitelnějšího, třeba boost matrix:
http://www.boost.org/doc/libs/1_53_0/libs/numeric/ublas/doc/matrix.htm
Název: Re:Nejasnost v C++
Přispěvatel: vyvojar 11. 04. 2013, 07:29:05
Co se s tim patlat :)

 
Kód: [Vybrat]
const int rows = 10;
 int ** matrix =  (int **)new char[sizeof(int *) * rows ];
Název: Re:Nejasnost v C++
Přispěvatel: Jakub Galgonek 11. 04. 2013, 07:56:43
Co se s tim patlat :)

Kód: [Vybrat]
const int rows = 10;
 int ** matrix =  (int **)new char[sizeof(int *) * rows ];

Nemůže v tomto případě (u některých architektur) nastat problém se zarovnáním? To přetypování by dokonce za jistých okolností, pokud se nepletu, mohlo změnit hodnotu adresy vrácené new.
Název: Re:Nejasnost v C++
Přispěvatel: vyvojar 11. 04. 2013, 08:10:55
Co se s tim patlat :)

Kód: [Vybrat]
const int rows = 10;
 int ** matrix =  (int **)new char[sizeof(int *) * rows ];

Nemůže v tomto případě (u některých architektur) nastat problém se zarovnáním? To přetypování by dokonce za jistých okolností, pokud se nepletu, mohlo změnit hodnotu adresy vrácené new.

Tak to nevim, snad by se nějaká optimalizace zarovnání nebo něco takového musela povolit explicitně. Sémanticky ten příklad dává smysl, tak by se to mělo doufám přeložit a taky fungovat očekávaným způsobem.
Název: Re:Nejasnost v C++
Přispěvatel: games 11. 04. 2013, 08:56:41
Tak to nevim, snad by se nějaká optimalizace zarovnání nebo něco takového musela povolit explicitně. Sémanticky ten příklad dává smysl, tak by se to mělo doufám přeložit a taky fungovat očekávaným způsobem.
Toto opravdu fungovat nemusí, alokátor pro char může vrátit adresu zarovnanou na modulo sizeof(char), což většinou bývá méně než sizeof(int*). Pak na některých architekturách dostaneš misaligned exception. Je to prasárna.
Název: Re:Nejasnost v C++
Přispěvatel: vyvojar 11. 04. 2013, 09:49:58
Tak to nevim, snad by se nějaká optimalizace zarovnání nebo něco takového musela povolit explicitně. Sémanticky ten příklad dává smysl, tak by se to mělo doufám přeložit a taky fungovat očekávaným způsobem.
Toto opravdu fungovat nemusí, alokátor pro char může vrátit adresu zarovnanou na modulo sizeof(char), což většinou bývá méně než sizeof(int*). Pak na některých architekturách dostaneš misaligned exception. Je to prasárna.
Škoda, že autor nenapsal, pro jakou architekturu to potřebuje. Tohle se určitě nebude týkat klasických pc, tam by to mělo být ok.
Název: Re:Nejasnost v C++
Přispěvatel: games 11. 04. 2013, 10:03:10
Škoda, že autor nenapsal, pro jakou architekturu to potřebuje. Tohle se určitě nebude týkat klasických pc, tam by to mělo být ok.
Klasických PC se to taky týká, tam to sice nespadne, ale misaligned access do paměti je mnohem pomalejší než aligned access. Jinak se to týká ARMu, PowerPC a mnoha dalších architektur.
Název: Re:Nejasnost v C++
Přispěvatel: Jakub Galgonek 11. 04. 2013, 10:07:59
Škoda, že autor nenapsal, pro jakou architekturu to potřebuje. Tohle se určitě nebude týkat klasických pc, tam by to mělo být ok.

Navíc norma v takových případech často říká, že výsledek takových "pochybných" operací je nedefinovaný. Toho pak kompilátor může využít k nějakým drsných (a nechtěným) optimalizacím.
Název: Re:Nejasnost v C++
Přispěvatel: vyvojar 11. 04. 2013, 10:08:15
Škoda, že autor nenapsal, pro jakou architekturu to potřebuje. Tohle se určitě nebude týkat klasických pc, tam by to mělo být ok.
Klasických PC se to taky týká, tam to sice nespadne, ale misaligned access do paměti je mnohem pomalejší než aligned access. Jinak se to týká ARMu, PowerPC a mnoha dalších architektur.

Proč je to vůbec pomalejší? Prostě procesor pošle na adresovou sběrnici adresu, ze které chce číst a hotovo, ne ? :D
Název: Re:Nejasnost v C++
Přispěvatel: Jakub Neburka 11. 04. 2013, 10:10:39
Dobrý den, chtěl bych Vás poprosit o radu. Když jsem se snažil v cpp vytvořit dynamicky matici, nakonec se mi nepodařilo zkompilovat nic jiného než:

Kód: [Vybrat]
int **prvky;

typedef int* uint;

prvky = new uint[dimx];

for ( int j = 0; j < dimy; j++)
{
   prvky[j] = new int[dimy];
}

Ale co jsem nepochopil, proč to nejde udělat bez typedef nového typu uint.

Nevíte prosím, jaký mechanismus, předpis, zabraňuje použití:  prvky= new (int*)[dimx];

děkuji za případnou radu.
Honza

Úkoly na FIT dají jednomu zabrat co? :D Měl bych jeden takový tip: Pro reprezentaci matice není nutné použít 2D pole. Jde to dost dobře i s jednorozměrným :)
Název: Re:Nejasnost v C++
Přispěvatel: games 11. 04. 2013, 10:31:41
Proč je to vůbec pomalejší? Prostě procesor pošle na adresovou sběrnici adresu, ze které chce číst a hotovo, ne ? :D
Sběrnice je třeba 64-bitová. Když chce procesor číst 64-bitovou hodnotu z adresy 0x1000, přečte to najednou. Když chce číst z adresy 0x1001, musí přečíst 0x1000 a 0x1008 a složit to dohromady (zjednodušeně řečeno, fyzické adresy do paměti na sběrnici budou ve skutečnosti CPU adresa děleno šířka sběrnice).
Název: Re:Nejasnost v C++
Přispěvatel: vyvojar 11. 04. 2013, 10:39:18
Proč je to vůbec pomalejší? Prostě procesor pošle na adresovou sběrnici adresu, ze které chce číst a hotovo, ne ? :D
Sběrnice je třeba 64-bitová. Když chce procesor číst 64-bitovou hodnotu z adresy 0x1000, přečte to najednou. Když chce číst z adresy 0x1001, musí přečíst 0x1000 a 0x1008 a složit to dohromady (zjednodušeně řečeno, fyzické adresy do paměti na sběrnici budou ve skutečnosti CPU adresa děleno šířka sběrnice).

Hm, stejně mi není úplně jasné, proč by se nedalo číst z jakékoliv adresy. Nebo tam ten přístup prostě vůbec není? Jakože nejmenší možná adresovatelná jednotka v paměti je ve skutečnosti šířka sběrnice a ne jeden bajt?
Název: Re:Nejasnost v C++
Přispěvatel: games 11. 04. 2013, 10:44:47
Jakože nejmenší možná adresovatelná jednotka v paměti je ve skutečnosti šířka sběrnice a ne jeden bajt?
Ano je to tak. CPU vždycky přečte tolik dat kolik je šířka sběrnice.