|
| 3-dimensional array - problem ved > 50 Fra : jma |
Dato : 21-06-06 10:25 |
|
Hej,
Jeg bruger et 3-dimensionalt array:
float arrfValue[250][250][iHours];
- hvor iHours er integer.
Så længe iHours er 50 eller under er der ingen problemer, men nu har jeg
fået brug for at sætte iHours til 60 eller 72. Det giver dog en
segmentation fault... Er der nogen begrænsninger i hvor stort array'et kan
være?
Håber på hjælp
På forhånd tak,
Jan
| |
Thorsten Ottosen (21-06-2006)
| Kommentar Fra : Thorsten Ottosen |
Dato : 21-06-06 10:33 |
|
jma wrote:
> Hej,
> Jeg bruger et 3-dimensionalt array:
> float arrfValue[250][250][iHours];
> - hvor iHours er integer.
>
> Så længe iHours er 50 eller under er der ingen problemer, men nu har jeg
> fået brug for at sætte iHours til 60 eller 72. Det giver dog en
> segmentation fault... Er der nogen begrænsninger i hvor stort array'et kan
> være?
Det kan være en stack-overflow som giver din fejl. Prøv at lave array'et
på heapen.
-Thorsten
| |
jma (21-06-2006)
| Kommentar Fra : jma |
Dato : 21-06-06 10:40 |
|
On Wed, 21 Jun 2006 11:32:30 +0200, Thorsten Ottosen wrote:
> jma wrote:
>> Hej,
>> Jeg bruger et 3-dimensionalt array:
>> float arrfValue[250][250][iHours];
>> - hvor iHours er integer.
>>
>> Så længe iHours er 50 eller under er der ingen problemer, men nu har jeg
>> fået brug for at sætte iHours til 60 eller 72. Det giver dog en
>> segmentation fault... Er der nogen begrænsninger i hvor stort array'et kan
>> være?
>
> Det kan være en stack-overflow som giver din fejl. Prøv at lave array'et
> på heapen.
ok - vil du være så venlig at fortælle mig hvordan jeg gør det? Jeg er
ikke så stiv i c/c++. tak.
> -Thorsten
| |
jma (21-06-2006)
| Kommentar Fra : jma |
Dato : 21-06-06 10:45 |
|
On Wed, 21 Jun 2006 11:39:38 +0200, jma wrote:
> On Wed, 21 Jun 2006 11:32:30 +0200, Thorsten Ottosen wrote:
>
>> jma wrote:
>>> Hej,
>>> Jeg bruger et 3-dimensionalt array:
>>> float arrfValue[250][250][iHours];
>>> - hvor iHours er integer.
>>>
>>> Så længe iHours er 50 eller under er der ingen problemer, men nu har jeg
>>> fået brug for at sætte iHours til 60 eller 72. Det giver dog en
>>> segmentation fault... Er der nogen begrænsninger i hvor stort array'et kan
>>> være?
Det skal lige sige at segmentation fault sker allerede når jeg deklarerer
arrayet med float arrfValue[250][250][iHours];
| |
jma (21-06-2006)
| Kommentar Fra : jma |
Dato : 21-06-06 10:56 |
|
On Wed, 21 Jun 2006 11:45:23 +0200, jma wrote:
> On Wed, 21 Jun 2006 11:39:38 +0200, jma wrote:
>
>> On Wed, 21 Jun 2006 11:32:30 +0200, Thorsten Ottosen wrote:
>>
>>> jma wrote:
>>>> Hej,
>>>> Jeg bruger et 3-dimensionalt array:
>>>> float arrfValue[250][250][iHours];
>>>> - hvor iHours er integer.
>>>>
>>>> Så længe iHours er 50 eller under er der ingen problemer, men nu har jeg
>>>> fået brug for at sætte iHours til 60 eller 72. Det giver dog en
>>>> segmentation fault... Er der nogen begrænsninger i hvor stort array'et kan
>>>> være?
>
> Det skal lige sige at segmentation fault sker allerede når jeg deklarerer
> arrayet med float arrfValue[250][250][iHours];
ok - det sidste er misvisende:
Det giver segmentation fault når jeg angiver f.eks.:
float arrfValue[250][250][72];
altså med en fast værdi. Derimod er float arrfValue[250][250][48]; ok. Så
der må næsten være en øvre grænse...
250*250*50 = 3.125.000 - skulle der være en grænse deromkring ???
| |
Thorsten Ottosen (21-06-2006)
| Kommentar Fra : Thorsten Ottosen |
Dato : 21-06-06 12:15 |
|
jma wrote:
> On Wed, 21 Jun 2006 11:32:30 +0200, Thorsten Ottosen wrote:
>
>
>>jma wrote:
>>
>>>Hej,
>>>Jeg bruger et 3-dimensionalt array:
>>>float arrfValue[250][250][iHours];
>>>- hvor iHours er integer.
>>>
>>>Så længe iHours er 50 eller under er der ingen problemer, men nu har jeg
>>>fået brug for at sætte iHours til 60 eller 72. Det giver dog en
>>>segmentation fault... Er der nogen begrænsninger i hvor stort array'et kan
>>>være?
>>
>>Det kan være en stack-overflow som giver din fejl. Prøv at lave array'et
>>på heapen.
>
>
> ok - vil du være så venlig at fortælle mig hvordan jeg gør det? Jeg er
> ikke så stiv i c/c++. tak.
Er det C eller C++ du koder i?
Arrays er noget rod, ikke mindst for begyndere. Der er flere udmærkede
libs til C++:
http://www.boost.org/libs/multi_array/doc/index.html
eller
http://synesis.com.au/software/stlsoft/help/classstlsoft_1_1fixed__array__3d.html
-Thorsten
| |
jma (21-06-2006)
| Kommentar Fra : jma |
Dato : 21-06-06 13:07 |
|
On Wed, 21 Jun 2006 13:15:16 +0200, Thorsten Ottosen wrote:
>>>Det kan være en stack-overflow som giver din fejl. Prøv at lave array'et
>>>på heapen.
>>
>>
>> ok - vil du være så venlig at fortælle mig hvordan jeg gør det? Jeg er
>> ikke så stiv i c/c++. tak.
>
> Er det C eller C++ du koder i?
>
> Arrays er noget rod, ikke mindst for begyndere. Der er flere udmærkede
> libs til C++:
>
> http://www.boost.org/libs/multi_array/doc/index.html
>
> eller
>
> http://synesis.com.au/software/stlsoft/help/classstlsoft_1_1fixed__array__3d.html
>
> -Thorsten
Ok. Tak for det. Har vist egentlig ok styr på arrays, men forstår ikke at
jeg får den fejl. Har fundet ud af at jeg kan lave et array sådan:
float arrfValue[250][200][62];
men ikke:
float arrfValue[250][200][63]; eller større!
Dvs. maks.:
250*200*62 = 3.100.000 floats er ok
mens,
250*200*63 = 3.150.000 floats giver segmentation fault.
Men jeg forestiller mig at det har noget med et memory limit at gøre!??!
men ved det ikke!
Nu har jeg dog løst problemet ved at køre programmet ad 2 omgange, så jeg
kan nøjes med værdier mindre end 63 i 3. felt... Det er ok for denne
løsning.
Tak for hjælpen,
Mvh Jan
| |
Thorsten Ottosen (21-06-2006)
| Kommentar Fra : Thorsten Ottosen |
Dato : 21-06-06 14:16 |
|
jma wrote:
> On Wed, 21 Jun 2006 13:15:16 +0200, Thorsten Ottosen wrote:
>
>
>>>>Det kan være en stack-overflow som giver din fejl. Prøv at lave array'et
>>>>på heapen.
> Ok. Tak for det. Har vist egentlig ok styr på arrays, men forstår ikke at
> jeg får den fejl. Har fundet ud af at jeg kan lave et array sådan:
>
> float arrfValue[250][200][62];
>
> men ikke:
> float arrfValue[250][200][63]; eller større!
>
> Dvs. maks.:
> 250*200*62 = 3.100.000 floats er ok
>
> mens,
> 250*200*63 = 3.150.000 floats giver segmentation fault.
>
> Men jeg forestiller mig at det har noget med et memory limit at gøre!??!
> men ved det ikke!
Nogle compilere tillader vist at man definerer størrelsen af stakken.
> Nu har jeg dog løst problemet ved at køre programmet ad 2 omgange, så jeg
> kan nøjes med værdier mindre end 63 i 3. felt... Det er ok for denne
> løsning.
Det er ikke normalt at placere flere magabytes direkte på stacken. Du
risikerer at dit program crasher med en anden compiler.
-Thorsten
| |
Kent Friis (21-06-2006)
| Kommentar Fra : Kent Friis |
Dato : 21-06-06 17:12 |
|
Den Wed, 21 Jun 2006 15:16:22 +0200 skrev Thorsten Ottosen:
> jma wrote:
>
>> Nu har jeg dog løst problemet ved at køre programmet ad 2 omgange, så jeg
>> kan nøjes med værdier mindre end 63 i 3. felt... Det er ok for denne
>> løsning.
>
> Det er ikke normalt at placere flere magabytes direkte på stacken. Du
> risikerer at dit program crasher med en anden compiler.
Hvis vi lige ser bort fra embeddede systemer, der har deres helt egne
begrænsninger, hvilke compilere har så problemer med at placere
flere megabytes på stack'en? Det var da sådan nogen problemer man havde
i de gamle DOS-dage, med DS og ES registre. Men i et moderne 32- eller
64-bit fladt memory-layout, med stacken i den ene ende af de 2 GB (eller
2^64), og heap'en i den anden, kan det da fra compilerens synspunkt
være bedøvende ligegyldigt om man placerer sine variable på stack'en
eller heap'en.
Hvorimod for programmøren er det en stor fordel af placere sine
variable på stack'en, hvor man ikke behøver bekymre sig om memory
leaks m.m, eller de deraf følgende workarounds så som at genopfinde
tidligere tiders tåbeligheder som garbage-collection.
Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).
| |
Arne Vajhøj (22-06-2006)
| Kommentar Fra : Arne Vajhøj |
Dato : 22-06-06 03:06 |
|
Kent Friis wrote:
> Hvis vi lige ser bort fra embeddede systemer, der har deres helt egne
> begrænsninger, hvilke compilere har så problemer med at placere
> flere megabytes på stack'en? Det var da sådan nogen problemer man havde
> i de gamle DOS-dage, med DS og ES registre. Men i et moderne 32- eller
> 64-bit fladt memory-layout, med stacken i den ene ende af de 2 GB (eller
> 2^64), og heap'en i den anden, kan det da fra compilerens synspunkt
> være bedøvende ligegyldigt om man placerer sine variable på stack'en
> eller heap'en.
>
> Hvorimod for programmøren er det en stor fordel af placere sine
> variable på stack'en, hvor man ikke behøver bekymre sig om memory
> leaks m.m, eller de deraf følgende workarounds så som at genopfinde
> tidligere tiders tåbeligheder som garbage-collection.
Det er ikke et compiler issue men et styre system issue.
Windows EXE filer har stående en stack size i headeren.
Default er 1 MB.
MS VC++ kan udvide den med /Fnnnnnnnn
GCC kan udvide den med -Wl,--stack=nnnnnnnn
Og det er ikke lavet for at genere programmørerne.
Hvis alle programmer bare var 1 process = 1 tråd, så kunne
man have lavet det som du gerne vil have det.
Men Windows er designet til multithreaded apps.
Og hver tråd får sin egen stak af 1 MB eller den angivne
størrelse.
Og derfor kan stakken ikke bare vokse nedad. Der kan ligge
en anden tråds stak der.
[det betyder også at antal tråde * stack size < 2 GB på
32 bit Windows !]
Surt show.
Arne
| |
Arne Vajhøj (22-06-2006)
| Kommentar Fra : Arne Vajhøj |
Dato : 22-06-06 03:18 |
|
Arne Vajhøj wrote:
> Det er ikke et compiler issue men et styre system issue.
>
> Windows EXE filer har stående en stack size i headeren.
>
> Default er 1 MB.
>
> MS VC++ kan udvide den med /Fnnnnnnnn
>
> GCC kan udvide den med -Wl,--stack=nnnnnnnn
>
> Og det er ikke lavet for at genere programmørerne.
>
> Hvis alle programmer bare var 1 process = 1 tråd, så kunne
> man have lavet det som du gerne vil have det.
>
> Men Windows er designet til multithreaded apps.
>
> Og hver tråd får sin egen stak af 1 MB eller den angivne
> størrelse.
>
> Og derfor kan stakken ikke bare vokse nedad. Der kan ligge
> en anden tråds stak der.
>
> [det betyder også at antal tråde * stack size < 2 GB på
> 32 bit Windows !]
Og på Linux (x86) er der også en limit.
Default er på min Linux 10 MB.
Den kan ses med:
ulimit -a
Og ændres med:
ulimit -s nnnnnnnn
Arne
| |
Kent Friis (22-06-2006)
| Kommentar Fra : Kent Friis |
Dato : 22-06-06 17:17 |
|
Den Wed, 21 Jun 2006 22:18:17 -0400 skrev Arne Vajhøj:
>
> Og på Linux (x86) er der også en limit.
>
> Default er på min Linux 10 MB.
>
> Den kan ses med:
> ulimit -a
stack size (kbytes) unlimited
Ikke nogen begrænsning her, så det må være noget din distro sætter
op.
Hvordan finder man nemmest et programs stack-forbrug i et program
der kører? Jeg har et program der bruger temmelig meget stack
(kræver en speciel libSDL.so uden thread-support), ikke pga. variable,
men fordi det er hyper-rekursivt.
(worst-case er 120.000, rekursions-niveauer, og det er kun fordi
programmet er hardkodet til at køre i 800x600).
Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).
| |
Bo Ørsted Andresen (22-06-2006)
| Kommentar Fra : Bo Ørsted Andresen |
Dato : 22-06-06 17:40 |
|
Kent Friis wrote:
> stack size (kbytes) Â Â Â Â unlimited
>
> Ikke nogen begrænsning her, så det må være noget din distro sætter
> op.
PÃ¥ mine maskiner (Gentoo) og en maskine jeg har adgang til (Debian) ser det
ud til at begge distroer sætter den til 8 MB så.
> Hvordan finder man nemmest et programs stack-forbrug i et program
> der kører?
Jeg må indrømme, at jeg ikke er sikker. Har ikke kunnet finde nogen
ordentlig dokumentation. Men hvad med?
# grep VmStk /proc/`pidof program`/status
--
Bo Andresen
| |
Kent Friis (22-06-2006)
| Kommentar Fra : Kent Friis |
Dato : 22-06-06 19:00 |
|
Den Thu, 22 Jun 2006 18:39:33 +0200 skrev Bo Ørsted Andresen:
> Kent Friis wrote:
>
>> stack size (kbytes) unlimited
>>
>> Ikke nogen begrænsning her, så det må være noget din distro sætter
>> op.
>
> På mine maskiner (Gentoo) og en maskine jeg har adgang til (Debian) ser det
> ud til at begge distroer sætter den til 8 MB så.
>
>> Hvordan finder man nemmest et programs stack-forbrug i et program
>> der kører?
>
> Jeg må indrømme, at jeg ikke er sikker. Har ikke kunnet finde nogen
> ordentlig dokumentation. Men hvad med?
>
> # grep VmStk /proc/`pidof program`/status
Med "i et program" mente jeg inde fra programmet. Programmet ved bedst
selv hvornår det er dybest i rekursionen.
Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).
| |
Arne Vajhøj (23-06-2006)
| Kommentar Fra : Arne Vajhøj |
Dato : 23-06-06 00:34 |
|
Kent Friis wrote:
> Hvordan finder man nemmest et programs stack-forbrug i et program
> der kører? Jeg har et program der bruger temmelig meget stack
> (kræver en speciel libSDL.so uden thread-support), ikke pga. variable,
> men fordi det er hyper-rekursivt.
Tager adressen på en stak variabel før du starter og der
hvor du vil måle og trækker dem fra hinanden.
Til inspiration:
#include <stdio.h>
int depth = 0;
int base;
void small(int a1)
{
int v1 = 1;
if(depth < 20)
{
depth++;
printf("small, depth = %d, stack size = %d, stack per call =
%d\n",depth,base-(int)&v1,(base-(int)&v1)/depth);
small(a1+v1);
printf("small, depth = %d, stack size = %d, stack per call =
%d\n",depth,base-(int)&v1,(base-(int)&v1)/depth);
depth--;
}
}
void big(int a1,int a2,int a3,int a4,int a5)
{
int v1 = 1;
int v2 = 2;
int v3 = 3;
int v4 = 4;
int v5 = 5;
if(depth < 20)
{
depth++;
printf("big, depth = %d, stack size = %d, stack per call =
%d\n",depth,base-(int)&v5,(base-(int)&v5)/depth);
big(a1+v1,a2+v2,a3+v3,a4+v4,a5+v5);
printf("big, depth = %d, stack size = %d, stack per call =
%d\n",depth,base-(int)&v5,(base-(int)&v5)/depth);
depth--;
}
}
int main()
{
int v = 0;
base = (int)&v;
small(0);
big(0,0,0,0,0);
return 0;
}
Arne
| |
Kent Friis (23-06-2006)
| Kommentar Fra : Kent Friis |
Dato : 23-06-06 15:20 |
|
Den Thu, 22 Jun 2006 19:34:11 -0400 skrev Arne Vajhøj:
> Kent Friis wrote:
>> Hvordan finder man nemmest et programs stack-forbrug i et program
>> der kører? Jeg har et program der bruger temmelig meget stack
>> (kræver en speciel libSDL.so uden thread-support), ikke pga. variable,
>> men fordi det er hyper-rekursivt.
>
> Tager adressen på en stak variabel før du starter og der
> hvor du vil måle og trækker dem fra hinanden.
D'oh
Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).
| |
Bertel Lund Hansen (21-06-2006)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 21-06-06 15:14 |
|
jma skrev:
>> Det kan være en stack-overflow som giver din fejl. Prøv at lave array'et
>> på heapen.
> ok - vil du være så venlig at fortælle mig hvordan jeg gør det? Jeg er
> ikke så stiv i c/c++. tak.
Hvis det er C, så gøres det sådan:
int main (void) {
float *arrfValue, size;
int iHours;
iHours=1000;
size=sizeof(float)*250*250*iHours;
printf("Size: %f\n",size);
arrfValue=malloc(size);
if (arrfValue == NULL) {
fprintf (stderr, "(1) Ak og ve! malloc() gik i ge'.\n");
exit (EXIT_FAILURE);
}
fprintf (stderr, "All went well!\n");
return EXIT_SUCCESS;
}
Med malloc() låser man et område i hukommelsen. Det frigives
automatisk når programmet afsluttes, men hvis man opretter i en
subrutine som kaldes mange gange uden at man frigiver området
bagefter, så bliver der mindre og mindre hukommelse, og til sidst
crasher programmet.
Selv om arrfValue i ovenstående er en pointer, kan du bare bruge
den som et almindeligt array (det er nemlig også en pointer).
--
Bertel
http://bertel.lundhansen.dk/ http://fiduso.dk/
| |
Simon (29-06-2006)
| Kommentar Fra : Simon |
Dato : 29-06-06 21:42 |
|
Bertel Lund Hansen wrote:
>>ok - vil du være så venlig at fortælle mig hvordan jeg gør det? Jeg er
>>ikke så stiv i c/c++. tak.
> size=sizeof(float)*250*250*iHours;
> printf("Size: %f\n",size);
> arrfValue=malloc(size);
>
> Selv om arrfValue i ovenstående er en pointer, kan du bare bruge
> den som et almindeligt array (det er nemlig også en pointer).
Jo, men så er det jo et én-dimensionelt array. Han er jo ude efter et 3D
array, og så skal der også reserveres plads til pointerne. Jeg har lavet
en simpel funktion jeg plejer at bruge til at allokere plads til 3D
arrays (put selv dine malloc checks ind hvis du er til den slags):
float ***alloc_3d_float(int n1, int n2, int n3)
{
float ***iii, **ii, *i;
int j;
iii = (float ***) malloc(n1 * sizeof(float **));
ii = (float **) malloc(n1 * n2 * sizeof(float *));
iii[0] = ii;
for (j = 1; j < n1; j++) {
iii[j] = iii[j - 1] + n2;
}
i = (float *) malloc(n1 * n2 * n3 * sizeof(float));
ii[0] = i;
for (j = 1; j < n1 * n2; j++) {
ii[j] = ii[j - 1] + n3;
}
return iii;
}
Ang. seg. faulten er det som Thorsten skriver sikkert et stack-overflow.
Er dine forward erklæringer korrekte?
Mvh
Simon
| |
Jesper Skriver (30-06-2006)
| Kommentar Fra : Jesper Skriver |
Dato : 30-06-06 11:59 |
|
On Thu, 29 Jun 2006 22:41:53 +0200, Simon wrote:
> Bertel Lund Hansen wrote:
>>>ok - vil du være så venlig at fortælle mig hvordan jeg gør det? Jeg er
>>>ikke så stiv i c/c++. tak.
>
>> size=sizeof(float)*250*250*iHours;
>> printf("Size: %f\n",size);
>> arrfValue=malloc(size);
>>
>> Selv om arrfValue i ovenstående er en pointer, kan du bare bruge
>> den som et almindeligt array (det er nemlig også en pointer).
>
> Jo, men så er det jo et én-dimensionelt array. Han er jo ude efter et 3D
> array, og så skal der også reserveres plads til pointerne. Jeg har lavet
> en simpel funktion jeg plejer at bruge til at allokere plads til 3D
> arrays (put selv dine malloc checks ind hvis du er til den slags):
Det vil nu vaere noget nemmere at goere noget ala
typedef struct foo_ {
float[CONST_A][CONST_B][CONST_c];
} foo;
foo *
alloc_foo (void)
{
return (malloc(sizeof(foo)));
}
--
Jesper Skriver, CCIE #5456
| |
|
|