Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: 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ž:
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
-
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.
-
Skutečně, děkuji.
Nevíte do hloubky, co Ty závorky způsobily, že to nešlo přeložit?
Honza
-
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.
-
#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;
}
-
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 :)
-
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.
-
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.
-
taky vraci void* stejne jako malloc.
Musím tě zklamat, ale nemáš pravdu.
-
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/
-
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:
struct c {
int x;
};
int main() {
(new c)->x = 0;
}
-
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
-
Co se s tim patlat :)
const int rows = 10;
int ** matrix = (int **)new char[sizeof(int *) * rows ];
-
Co se s tim patlat :)
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.
-
Co se s tim patlat :)
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.
-
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.
-
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.
-
Š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.
-
Š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.
-
Š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
-
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ž:
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 :)
-
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).
-
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?
-
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.