Avatar billede lassel Nybegynder
08. maj 2004 - 15:06 Der er 20 kommentarer og
1 løsning

Dynamisk lagerallokering - 2dim array

Hejsa.

Jeg er stadig lidt ny i faget, så bær over med mig :)

I tidligere kode før følgende er brugeren blevet kørt igennem en række spørgsmål med mere. Dette har resulteret i udfyldelse af følgende struct:
struct playerinfo {
  char name_str[4];
  int m;
  int n;
  int p;
};

Som er blevet type defineret som:
typedef struct playerinfo playerinfo;

I den funktion jeg står i nu har jeg brug for at allokere lager til et 2 dimensionelt array. Her er jeg meget usikker på hvoledes disse fungere, men jeg er kommet frem til foelgende:
storage = malloc((player.p+1)*(player.n+2)*sizeof(int));

storage er sat som int = *storage;
Det virker umiddelbart ok med henblik på det jeg skal bruge det til, men her kommer spørgsmålene:

1) Hvordan navigerer jeg bedst rundt i dette array?
Ex. ved at pointe mig frem *(storage + 0 + 0) for at vælge øverste højre hjørne hvis man ser array'et som en tabel?

2) Hvordan nulstiller jeg mest effektivt hele array'et?
Havde engang hørt om en smart lille funktion til dette, kan ikke huske den...

3) Hvordan laver jeg et output som følgende?
Hvis p = 5 og n = 3.
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Altså p til højre og n nedaf.

Jeg siger mange gange tak på forhånd i så fald folk kan hjælpe mig. Syntes ligesom jeg pludselig rendte ind i en mur af ting jeg ikke forstod og kendte til. Hvis folk har links til hvor jeg kan læse om ovenstående er disse og meget velkomne.
Avatar billede arne_v Ekspert
08. maj 2004 - 15:44 #1
re 2)

memset(storage,0,n*p);

lyder som en god måde
Avatar billede arne_v Ekspert
08. maj 2004 - 15:46 #2
re 1)

du allokerer et 1D array så du er nødt til at konvertere fra 2D til 1D

storage[row*p+col]
Avatar billede arne_v Ekspert
08. maj 2004 - 15:47 #3
re 3)

for(row=0;row<n;row++)
{
  for(col=0;col<p;col++)
  {
      printf(" %d",storage[row*p+col]);
  }
  printf("\n");
}
Avatar billede lassel Nybegynder
08. maj 2004 - 15:57 #4
3) yes, også i den stil jeg endte... kunne bare ikke få det til at fungere korrekt pga. den åbenbart, som du pointerede, så det som 2D men jeg arbejdede med det som 1D. Men den del fungerer nu, tak.

2) memset, hmmm, jeg har forsøgt at bruge den efter jeg satte variabler i tabellen til et par værdier, men det er som om den kun nulstiller 0,0. Hvis jeg f.eks. har sat et 2*2 array og sat 0,1 til 4 og 0,0 til 1. Og derefter kører memset, så sletter den kun 0,0...

1) Hmmm, okay... men det er jo egentlig et 2D array jeg har brug for når jeg skal bruge en tabel som f.eks.

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Og alle værdier skal kunne betragtes hver for sig og fremstå forskellige...


Mange tak for dine besvarelser indtil nu. Det er til stor hjælp.
Avatar billede arne_v Ekspert
08. maj 2004 - 16:03 #5
re 2)

Hvis storage ikke er en char pointer men en int pointer så:

memset(storage,0,n*p*sizeof(int));
Avatar billede arne_v Ekspert
08. maj 2004 - 16:03 #6
re 1)

Den kode jeg skitserede skriver et 1D array ud som et 2D array
Avatar billede lassel Nybegynder
08. maj 2004 - 16:09 #7
Jeg testede lige dit memset igen, og når jeg kører denne just efter at sætte nogle få værdier, så nulstiller den fint alt og outputter et 0-skema. Så den er god nu.

Men, nu er der noget sært i gære.

Hvis jeg efter et memset til 0 sætter følgende i et 5*4 array:

    storage[0*player.p + 0] = 1;
    storage[2*player.p + 0] = 3;
    storage[1*player.p + 2] = 4;

Får jeg outputtet

  1    0    0    0    0
  0    0    4    3    0
  3    0    0    0    0
  0    0    0    0    0

Hvorfor dælen skal det dumme 3-tal komme frem i 4,2? :(
Avatar billede arne_v Ekspert
08. maj 2004 - 16:27 #8
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  int row,col;
  int *storage;
  storage = (int *)malloc(4*5*sizeof(int));
  memset(storage,0,4*5*sizeof(int));
  storage[0*5 + 0] = 1;
  storage[2*5 + 0] = 3;
  storage[1*5 + 2] = 4;
  for(row=0;row<4;row++)
  {
      for(col=0;col<5;col++)
      {
        printf(" %d",storage[row*5+col]);
      }
      printf("\n");
  }
  return 0;
}

giver:

1 0 0 0 0
0 0 4 0 0
3 0 0 0 0
0 0 0 0 0

hos mig.
Avatar billede lassel Nybegynder
08. maj 2004 - 16:30 #9
Hmmmmmm.... tak for skabelonen... vil lige gå den igennem

Et hurtigt spørgsmål: hvorfor storage = (int *)malloc(4*5*sizeof(int));
med (int *) foran malloc?
Avatar billede arne_v Ekspert
08. maj 2004 - 16:32 #10
Nogen compilere giver warning hvis man ikke bruger den type cast andre
er ligeglade.

Jeg tog den med.
Avatar billede lassel Nybegynder
08. maj 2004 - 16:35 #11
Ok, gav ingen forskel ved min.

int *storage, row, col;

    print_new_game();   
    player = ask_name(player);
    player = ask_m(player);
    player = ask_n(player);
    player.n = player.n + 2; // ekstra col til rigtig numre og placeringer
    player = ask_p(player);
    player.p = player.p + 1; // ekstra row til facit
   
    /* Dynamisk allokering af array. */
   
    storage = (int *)malloc(player.p*player.n*sizeof(int));
    memset(storage,0,player.p*player.n*sizeof(int));
    storage[0*player.p + 0] = 1;
    storage[2*player.p + 0] = 7;
    storage[1*player.p + 2] = 4;

               
    for(row = 0; row < player.p; row++){
        for(col = 0; col < player.n; col++){
            printf("%4i ", storage[row*player.p + col]);
        }
        printf("\n");
    }

Giver stadig sært nok:

  1    0    0    0    0
  0    0    4    0    7
  7    0    0    0    0
  0    0    0    0    0

Sært at når jeg sætter et tal (f.eks. 7) i 3. række kolonne 1, så bliver den også sat i 2. række kolonne 5. Hmmmm, det er så tæt på det bare funker :D:D:D
Avatar billede lassel Nybegynder
08. maj 2004 - 16:40 #12
Og med:

    storage[0*player.p + 0] = 1;
    storage[2*player.p + 0] = 7;
    storage[1*player.p + 2] = 4;
    storage[3*player.p + 0] = 2;
    storage[1*player.p + 4] = 6;
    storage[1*player.p + 0] = 9;

  1    0    0    0    9
  9    0    4    0    6
  6    0    0    0    2
  2    0    0    0    0

Virker som om at tal der sættes i første kolonne sættes også i forrige rækkes sidste kolonne... hmmmm... ondt i hovedet snart
Avatar billede arne_v Ekspert
08. maj 2004 - 16:40 #13
Prøv lige at erstat

[  *player.p + ]

med

[  *player.n + ]
Avatar billede arne_v Ekspert
08. maj 2004 - 16:41 #14
Det er

række nummer * antal kolonner + kolonne nummer
Avatar billede lassel Nybegynder
08. maj 2004 - 16:42 #15
1    0    0    0    0
  0    9    0    4    0
  0    6    7    0    0
  0    0    0    2    0
Avatar billede lassel Nybegynder
08. maj 2004 - 16:46 #16
storage[0*player.n + 0] = 1;
    storage[2*player.n + 0] = 7;
    storage[1*player.n + 2] = 4;
    storage[3*player.n + 0] = 2;
    storage[1*player.n + 4] = 6;
    storage[1*player.n + 0] = 9;

  1    0    0    0    0
  9    0    4    0    6
  7    0    0    0    0
  2    0    0    0    0
Avatar billede lassel Nybegynder
08. maj 2004 - 16:49 #17
Nu virker det jo... du er bare supermand... tusind takker...

Et sidste hurtige spørgsmål som du kan give et "svar" på, er det rigtig forstået at når jeg allokerer på denne måde så kan jeg kalde funktioner med hele storage som f.eks. func(*storage) og derved arbejde med en ny funktion hvor den direkte kan behandle storage of senere return *storage?
Avatar billede arne_v Ekspert
08. maj 2004 - 16:54 #18
int *storage;
storage = (int *)malloc(...);
func(storage);

...

void func(int *storage)
{
  ...
}

lyder som det du vil.

ikke * i kaldet - og ingen grund til at returnere noget da du godt kan
ændre i det som storage peger på.
Avatar billede arne_v Ekspert
08. maj 2004 - 16:55 #19
og et svar
Avatar billede lassel Nybegynder
08. maj 2004 - 16:58 #20
Og selvom jeg har
int *storage;
storage = (int *)malloc(...);
func(storage);

inde i en anden funktion fungerer det stadig i andre... det er nødvendigt for mig først at allokere array i en funktion da jeg skal have brugeren til at besvare på dimensioner først...

Mange tak for hjælpen, du har hermed fået point.
Avatar billede arne_v Ekspert
08. maj 2004 - 17:19 #21
Det burde fungere fint.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester