[C] dynamische multidimensionele array van structures maken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Aan de hand van deze site begrijp ik nu ongeveer hoe multidimensionele dynamische arrays werken :
http://pw2.netcom.com/~tjensen/ptr/ch9x.htm

Maar hoe zorg ik er nu voor dat elke positie in de array weer naar een op een volgend gedeelte van structures verwijst. Wie heeft hier een goed voorbeeld stukje code van hoe zo iets aan te pakken.

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
Met een pointer i guess. Maareh, leg eens uit wat precies de onduidelijkheid want 't is een beetje summier.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Hoe doe ik zo iets, ik dacht zelf aan dit voorbeeld een beetje aanpassen :

aptr = malloc(nrows * ncols * sizeof(int));
rptr = malloc(nrows * sizeof(int *));

rptr[k] = aptr + (k * ncols);


1) creëer grote array met malloc rij * kolom * sizeof structure
2) creeer ruimte voor de structure met malloc rij * structure
3) vul nu de rptr

Ik mis nog wat zaken wie zou mij een beetje aan kunnen vullen.

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Er zijn globaal drie manieren om tweedimensionale structuren te maken:
  1. Met een statisch type. Bijvoorbeeld int a[12][34]; declareert een tweedimensionale array, waarvan de dimensies vaststaan. Als alleen het aantal kolommen bekend is, kun je nog iets als int (*a)[34] = malloc(sizeof(int)*34*rows); doen, maar als beide dimensies variabel zijn is dit geen geschikte aanpak.
  2. Met een dynamisch type. Bijvoorbeeld int a[rows][cols];. Deze zogenaamde variable-length arrays werken alleen in C99 (en nadrukkelijk niet in standaard C++) en hebben enkele beperkingen (je kunt ze bijvoorbeeld niet in een struct stoppen).
  3. Met een array-van-arrays. Hierbij is elk element van de eerste array (elke rij) een pointer naar een tweede array. Het type van zo'n structuur kan int** zijn, en de precieze dimensies kun je dan volledig at runtime bepalen. Nadeel is dat allocatie ingewikkelder is en indexering iets minder efficiënt, maar meestal zijn dat geen onoverkomelijke beperkingen.
Wat je zelf beschrijft is een variant van de derde optie, waarbij je twee losse allocaties doet (één voor de data in de tweedimensionale array zelf, en één voor de array van pointers.) Wat wil je dat wij daar nog aan toevoegen?

Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Je moet zien dat dit voor mij een heel groot bos is waarvan ik het geheel niet overzie. Dus een voorbeeld van hoe je hier mee begint. Hoe stop ik die struct bijv. in deze 2 dimensionele array. Rekening houden met malloc,

Gefeliciteerd Soultaker!

[ Voor 5% gewijzigd door lamko op 30-08-2011 21:41 . Reden: Felicitaties toegevoegd ]

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Als ik een tip mag geven: staar niet te veel naar code in eerste instantie maar probeer 't te visualiseren:
Ik heb geen zin om te photoshoppen/painten maar met een korte google kwam ik op iets wat ik (ongeveer) bedoel:
Afbeeldingslocatie: https://lh4.googleusercontent.com/-O-9UVBWkgzk/TijhEKx_Q7I/AAAAAAAAAHo/nEhNkFYoW0s/s400/tut6.png
Denk 't linksbovenste blokje even weg (of zie 't als de variabele die (een pointer naar) je array bevat). De bovenste rij is je feitelijke array; die bevat pointers naar structs; de "verticale" blokken eronder kun je zien als bytes van elke struct waarbij elke struct een eigen grootte heeft ("jagged array"). Als je 'm multi-dimensionaal wil (dus foo[x][y]) dan kun je de verticale blokken eronder natuurlijk ook gewoon pointers zetten naar je structs; trek vanuit elk blok een pijltje naar een struct (die je erbij tekent) en je bent er.

Heb je wel nog wat administratieve taken te tackelen (welk type struct bevat elk element etc.) maar dat is bijzaak.

[ Voor 6% gewijzigd door RobIII op 30-08-2011 22:24 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Maar als ik nou uit de code denk, dat zou bedenken dat ik twee pointer arrays moet creëren en ruimte voor de structure zelf die overigens altijd 3 bytes is. Betekend dit dan dat ik drie keer malloc moet gebruiken ?

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
lamko schreef op dinsdag 30 augustus 2011 @ 23:01:
Maar als ik nou uit de code denk, dat zou bedenken dat ik twee pointer arrays moet creëren en ruimte voor de structure zelf die overigens altijd 3 bytes is. Betekend dit dan dat ik drie keer malloc moet gebruiken ?
Als je nou eerst eens voor jezelf in pseudocode het "high level" algoritme uitschrijft, en dan, stukje-bij-beetje naar je gewenste taal omzet. Het zou handig/leerzaam zijn als je die pseudocode en het resultaat ervan zou willen posten. Dan zullen de mensen die niet zo roestig in C zijn als ik je vast kunnen vertellen of je gedachtegang klopt en/of waar je de fout in gaat.

[ Voor 20% gewijzigd door RobIII op 30-08-2011 23:20 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Dit pseudocode is errug pseudo ;)

code:
1
2
3
4
5
6
7
8
9
10
aptr = malloc int*
rowtr = malloc int*
structptr =malloc struct * row * col

for 0 ; row < aantalrow i++
   rowptr = aptr + ( i * col)

for rijen
   for col
        rowptr[r][c] = structptr++


Graag opbouwend advies.

[ Voor 11% gewijzigd door lamko op 31-08-2011 00:02 ]

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Dat is geen pseudocode, dat is half-assed C :P
Pseudo kun je gewoon in Nederlands schrijven en heeft (in eerste instantie) nog niets met mallocs en pointers van doen ;)

En stap, al is 't maar voor nu, van "aptr", "rowtr" en dergelijke afkortingen af. Als je moeite hebt een algoritme te kristalliseren is 't laatste wat je hersenen nodig hebben tijdens het uitdenken ervan wat aptr ook weer was tijdens het lezen van een zin/regel pseudocode.

Allemaal (opbouwend) advies dat vermoedelijk élke (enigszins ervaren danwel oldskool :P ) programmeur zal beamen.

[ Voor 63% gewijzigd door RobIII op 31-08-2011 00:35 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
Je maakt een array ( al dan niet dynamisch van grootte ) met pointers, die je vervolgens in een loop dynamisch initialiseert:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main( int argc, char* argv[] )
{
    int** array_van_pointers = (int**)malloc( sizeof(int*) * 10 );

    for( int i = 0; i < 10; ++i )
        array_van_pointers[ i ] = (int*)malloc( sizeof(int*) * i * 5 );

    for( int i = 0; i < 10; ++i )
    {
        for( int j = 0; j < i * 5; ++j )
            array_van_pointers[ i ][ j ] = i * j;
    }
    return 0;
}


- array_van_pointers[ 4 ] is nu een pointer naar een array van 20 int's
- array_van_pointers[ 5 ] is nu een pointer naar een array van 25 int's
etc.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Hier nog wat simpele pseudocode :)

code:
1
2
3
4
5
6
7
8
reserveer geheugen vooraantal rijen gegeven
reserveer geheugen voor aantal kolommen gegeven
loop door aantal rijen
laat elke rij naar een kolom verwijzen
einde loop
loop door rijen en kolommen
laat elke rij + kolom positie naar een structure verwijzen
einde loop


Ik heb van mijn half-assed C dit kunnen maken, maar ik zie hier nog niet veel in.
Het heeft nog enig schaafwerk nodig ;)

[ Voor 4% gewijzigd door lamko op 31-08-2011 16:07 ]

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
Huhu :N

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Graag wat meer onderbouwend advies!

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
lamko schreef op woensdag 31 augustus 2011 @ 15:28:
Graag wat meer onderbouwend advies!
- Graag wat meer info van jouw kant : heb je naar mijn voorbeeldcode gekeken? Doorheen gestapt met een debugger? Wat snap je er nog niet aan?
- Psuedocode hoor je te kunnen lezen als een 'verhaal'. Het gekrabbel dat jij daar neerkrast is onbruikbaar, ik hoop dat je dat zelf ook ziet? Zo niet: lees het eens hardop voor aan jezelf of iemand anders.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Ben er ook niet zo thuis in, vandaar enige schaafwerk ;) Die voorbeeld code ga ik eens door de debugger halen.
Dat heb ik nu gedaan maar ik begrijp daar nog niet uit hoe ik een structure erin integreer.

[ Voor 29% gewijzigd door lamko op 31-08-2011 16:05 ]

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
lamko schreef op woensdag 31 augustus 2011 @ 15:57:
Dat heb ik nu gedaan maar ik begrijp daar nog niet uit hoe ik een structure erin integreer.
Vervang alle int's door jouw struct type. ( behalve de int's in de for loops ofc )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Kan ik met dit stukje code hetzelfde doen, dwz int's door structs vervangen ? Hier ligt alles strak achterelkaar in het geheugen en dat is bij jouw code niet zo.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* Program 9.3 from PTRTUT10.HTM   6/13/97 */

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int **rptr;
    int *aptr;
    int *testptr;
    int k;
    int nrows = 5;     /* Both nrows and ncols could be evaluated */
    int ncols = 8;    /* or read in at run time */
    int row, col;

    /* we now allocate the memory for the array */

    aptr = malloc(nrows * ncols * sizeof(int));
    if (aptr == NULL)
    {
        puts("\nFailure to allocate room for the array");
        exit(0);
    }

    /* next we allocate room for the pointers to the rows */

    rptr = malloc(nrows * sizeof(int *));
    if (rptr == NULL)
    {
        puts("\nFailure to allocate room for pointers");
        exit(0);
    }

    /* and now we 'point' the pointers */

    for (k = 0; k < nrows; k++)
    {
        rptr[k] = aptr + (k * ncols);
    }

    /* Now we illustrate how the row pointers are incremented */
    printf("\n\nIllustrating how row pointers are incremented");
    printf("\n\nIndex   Pointer(hex)  Diff.(dec)");

    for (row = 0; row < nrows; row++)
    {
        printf("\n%d         %p", row, rptr[row]);
        if (row > 0)
        printf("              %d",(rptr[row] - rptr[row-1]));
    }
    printf("\n\nAnd now we print out the array\n");
    for (row = 0; row < nrows; row++)
    {
        for (col = 0; col < ncols; col++)
        {
            rptr[row][col] = row + col;
            printf("%d ", rptr[row][col]);
        }
        putchar('\n');
    }

    puts("\n");

    /* and here we illustrate that we are, in fact, dealing with
       a 2 dimensional array in a contiguous block of memory. */
    printf("And now we demonstrate that they are contiguous in memory\n");

    testptr = aptr;
    for (row = 0; row < nrows; row++)
    {
        for (col = 0; col < ncols; col++)
        {
            printf("%d ", *(testptr++));
        }
        putchar('\n');
    }

    return 0;
}

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op dinsdag 30 augustus 2011 @ 21:05:
  1. Met een statisch type. Bijvoorbeeld int a\[12]\[34]; declareert een tweedimensionale array, waarvan de dimensies vaststaan. Als alleen het aantal kolommen bekend is, kun je nog iets als int (*a)\[34] = malloc(sizeof(int)*34*rows); doen, maar als beide dimensies variabel zijn is dit geen geschikte aanpak.
  2. Met een dynamisch type. Bijvoorbeeld int a[rows][cols];. Deze zogenaamde variable-length arrays werken alleen in C99 (en nadrukkelijk niet in standaard C++) en hebben enkele beperkingen (je kunt ze bijvoorbeeld niet in een struct stoppen).
  3. Met een array-van-arrays. Hierbij is elk element van de eerste array (elke rij) een pointer naar een tweede array. Het type van zo'n structuur kan int** zijn, en de precieze dimensies kun je dan volledig at runtime bepalen. Nadeel is dat allocatie ingewikkelder is en indexering iets minder efficiënt, maar meestal zijn dat geen onoverkomelijke beperkingen.
4. Een ééndimensionale array, die je vervolgens indexeert middels row * numcols + col (of juist col * numrows + row).

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
lamko schreef op woensdag 31 augustus 2011 @ 17:03:
Kan ik met dit stukje code hetzelfde doen, dwz int's door structs vervangen ? Hier ligt alles strak achterelkaar in het geheugen en dat is bij jouw code niet zo.
Wat denk je zelf, zou dat kunnen?


Je topic begint steeds meer op een scriptrequest te lijken btw.

[ Voor 12% gewijzigd door farlane op 31-08-2011 20:40 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Ik kom er echt niet uit ben hier zowat al een week mee bezig. Beetje in de trant van pseudo dan kan ik het zelf wel verder uitwerken.

[ Voor 37% gewijzigd door lamko op 31-08-2011 21:40 ]

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 19-09 20:56
Wellicht is C dan op dit moment niet de juiste taal voor je? Ik denk dat het slim is eerst even naar een highlevel taal (zoals php) te kijken waar je eerst wat meer gewend kan raken aan het abstract denken, en dan later nog eens naar C te kijken.

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
lamko schreef op woensdag 31 augustus 2011 @ 21:39:
Ik kom er echt niet uit ben hier zowat al een week mee bezig. Beetje in de trant van pseudo dan kan ik het zelf wel verder uitwerken.
Ja maar wat wil je nu eigenlijk? Er zijn al diverse antwoorden/oplossingen/mogelijkheden gegeven maar blijkbaar zit het antwoord dat je wilt horen/zien er niet bij.

Mijn vragen zijn : Wat wil je precies en wat is er nog niet duidelijk?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Ik ben opzoek naar http://c-faq.com/aryptr/dynmuldimary.html de tweede array oplossing met structures.
Zodat ik het geheugen achterelkaar kan wegschrijven.
@Freeaqingme
Heb vooral bash gedaan ook een scripting taal zoals php. Het eerste gedeelte van C lukt ook wel alleen het low level C met pointers en zo daar gaat het wat mis.

And this !! Is to go even further beyond!!!


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 19:45
lamko schreef op woensdag 31 augustus 2011 @ 22:26:
Heb vooral bash gedaan ook een scripting taal zoals php. Het eerste gedeelte van C lukt ook wel alleen het low level C met pointers en zo daar gaat het wat mis.
Kan je dan niet beter wat meer oefenen op pointers? Uiteindelijk is dat niet zó moeilijk, gewoon goed opletten en het snappen. Ik zou dus niet direct beginnen met pointers van pointers (van pointers van... you get the picture). Dat compliceert de zaken alleen maar wat meer en kan voor verwarring zorgen. Zorg dus dat je pointers in algemene zin eerst snapt. Daarna kan je een stapje verder gaan en dan zit je in de huidige situatie.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
lamko schreef op woensdag 31 augustus 2011 @ 22:26:
Ik ben opzoek naar http://c-faq.com/aryptr/dynmuldimary.html de tweede array oplossing met structures.
Zodat ik het geheugen achterelkaar kan wegschrijven.
Snap je de eerste oplossing ( die hetzelfde is als de voorbeeldcode van mij ) wel dan ? Als je die/mijn code kunt omzetten naar struct's ipv int's dan kun je dat bij de tweede ook.

Als je dat niet kunt, moet je ook niet aan de tweede beginnen want die is nog minder voor de hand liggend.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
@farlane
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main( int argc, char* argv[] )
{
    struct** array_van_pointers = (struct**)malloc( sizeof(struct*) * 10 );

    for( int i = 0; i < 10; ++i )
        array_van_pointers[ i ] = (struct*)malloc( sizeof(struct*) * i * 5 );

    for( int i = 0; i < 10; ++i )
    {
        for( int j = 0; j < i * 5; ++j )
            array_van_pointers[ i ][ j ] = struct;
    }
    return 0;
}


Wat ik hier DUS niet aan begreep is, dan heb je dus een I van een structure groot en een J van een structure groot. En mijn andere gedachte was dat beide een pointer waren dus dat je dan weer ruimte voor de structure zelf moest reserveren. ik zag gewoon de combo niet van pointer en struct dat het samen doen.
Maar dat is niet zo, als ik het nog even goed lees : I is de pointer en J is de ruimte voor de structure waar alles wordt ingezet. _/-\o_

[ Voor 12% gewijzigd door lamko op 01-09-2011 15:10 ]

And this !! Is to go even further beyond!!!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Mja, je zegt het een beetje vaag. i en j zijn gewoon indices. Maar elke array_van_pointers[i] wijst naar een array van jouw structures. Met j indexeer je in die array, dus array_van_pointers[i][j] is een enkele struct.

Afbeeldingslocatie: https://lh4.googleusercontent.com/-O-9UVBWkgzk/TijhEKx_Q7I/AAAAAAAAAHo/nEhNkFYoW0s/s400/tut6.png

Dat eerste blokje linksboven is array_van_pointers zelf. Die wijst naar de rij van blokjes daar rechts van, dit zijn de array_van_pointers[i]'s met i van 0 tot 10. Elke kolom blokjes dat daaronder hangt zijn de structs zelf, dus array_van_pointers[i][j]

[ Voor 45% gewijzigd door .oisyn op 01-09-2011 15:07 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • lamko
  • Registratie: December 2001
  • Laatst online: 20-10-2024
Ik zeg het misschien vaag maar zo begrijp ik het :)
Deze tut http://www.codeproject.com/KB/cpp/pointers.aspx bracht me tot de goeie ingeving.

[ Voor 47% gewijzigd door lamko op 01-09-2011 16:01 ]

And this !! Is to go even further beyond!!!

Pagina: 1