/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
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

Søg
Reklame
Statistik
Spørgsmål : 177577
Tips : 31968
Nyheder : 719565
Indlæg : 6409071
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste