Avatar billede hurra Novice
29. marts 2008 - 07:50 Der er 12 kommentarer og
1 løsning

Dynamisk array i stacken

Jeg sidder og roder i noget kode jeg ikke selv har skrevet, og som ikke er super godt struktureret.

Der bliver oprettet en hel del arrays af forskellige typer. De er alle defineret med "magic numbers". e.g.

float measurements[95];

De 95 går igen 1000 steder (næsten) i kode, men alt efter hvad der skal måles på, er der måske kun 5 pladser der skal bruges i arrayet.

Jeg vil gerne lave størrelsen af arrayet dynamisk for at undgå det voldsomme overhead. Følgende vil løse mine problemer.

unsigned int arraySize = 95;
float *measurement = new float[arraySize];

Men så bliver det jo oprettet i på heapen, og så skal jeg huske at ryde op efter mig selv. Problemet ved det er igen, at koden ikke er specielt godt struktureret, og der er adskillige muligheder for  hvor der er returns.

Jeg ved godt en mulighed er at lave en label i bunde af funktionen, hvor efter alt oprydning og return findes, men hvis jeg gerne vil undgå det, kan jeg så ikke oprette en array af dynamisk størrelse, som ikke ligger på heapen ?
Avatar billede nielle Nybegynder
29. marts 2008 - 08:27 #1
Hvorfor så ikke bare:

unsigned int arraySize = 95;
float measurement[arraySize];
Avatar billede hurra Novice
29. marts 2008 - 11:11 #2
Det meget simple svar; Fordi det ikke virker :)

Det skal være et konstant udtryk der bruges til erklæring af arrayet på den måde, og jeg vil gerne ud over det konstante.
Avatar billede bertelbrander Novice
29. marts 2008 - 13:09 #3
I mange tilfælde vil du kunne opnå det ved at bruge en std::vector i stedet.
Den opfører sig på mange måder som et array, størrelsen kan sættes dynamisk og den rydder selv op efter sig.
Avatar billede arne_v Ekspert
29. marts 2008 - 15:16 #4
unsigned int arraySize = 95;
float measurement[arraySize];

virker kun i C99 - ikke i C89 og C++

#define ARRAY_SIZE 95
...
float measurement[ARRAY_SIZE];

virker i C og C++

const int ARRAY_SIZE = 95;
...
float measurement[ARRAY_SIZE];

virker i C++ - ikke i C

unsigned int arraySize = 95;
float *measurement = (float*) malloc(arraySize*sizeof(float));
...
free(measurement);

virker i C og C++ (allokerer på heap)

unsigned int arraySize = 95;
float *measurement = new float[arraySize];
...
delete[] measurement;

virker i C++ - ikke i C (allokerer på heap)

unsigned int arraySize = 95;
float *measurement = (float*) alloca(arraySize*sizeof(float));

er ikke ANSI C og C++ men virker med de fleste alligevel, allokerer
på stack men er noget gammeldags
Avatar billede soerenlyn Nybegynder
04. april 2008 - 09:48 #5
Jeg synes nu ikke det er så stort et problem at allokere ting på hoben - men du kunne vel lave en lokal variable i main - den vil dermed blive allokeret på stacken, og så vil du kunne bruge den indtil dit program terminerer...
Avatar billede hurra Novice
11. april 2008 - 09:38 #6
Undskyld jeg har været stille i noget tid.

Jeg valgte ikke at rette uhensigtsmæssighederne i den originale kode, og begyndte i stedet for helt for fra, og fik sat lidt styr på alle de andre ting der ikke virkede optimalt.

Bertel, du skal ha points for at komme med et konkret løsnings forslag. Kom med et svar.

Arne, du skal ha mange tak for at gi en god forklaring på hvad man kan med hvilke versioner af c.
Avatar billede hurra Novice
11. april 2008 - 09:43 #7
Jeg har forresten lige et tillægsspørgsmål der er meget tæt relateret.

Hvis nu jeg har oprettet et array af flere dimenssioner, og skal sende det til en funktion. Jeg bliver vel nødvendigvis nødt til at skuklle cast størrelsen, men hvordag?

Følgende virker ikke, men kan måske gi en bedre ide om hvad det er jeg prøver at gøre:
void f(int **a, int b, int h)
{
  int c = ((int[b][h])a)[1][1];
Avatar billede arne_v Ekspert
11. april 2008 - 13:36 #8
int *a
int a[]

kan bruges ens

int **a
int a[K][]

kan ikke bruges ens

der er stor forskel på et to dimensionelt array og et array af pointere til array

din specifikke kode bør virke uden cast overhovedet
Avatar billede hurra Novice
11. april 2008 - 14:02 #9
Jeg er ikke helt med, tangerende at jeg for første gang i historien ikke helt tror på dig arne_v ;-)

Med følgende kode vil c da temmelig sikkert ikke blive 5 (måske 4).
void f(int **a, int b, int h)
{
  int c = a[1][1];
}
void main()
{
  int a={{1, 2, 3},{4, 5, 6},{7, 8, 9}};
  f(a, 3, 3);
}

Men det vil virke hvis f bliver rettet til
void f(int a[3][3], int b, int h)

Jeg har lige læst dit svar et pat gange mere, og tror måske jeg forstår lidt mere hvad du mener, er det noget i stil med at hvis jeg bruger:
void f(int a[3][], int b, int h)
behøver jeg ikke at caste, men i dit oprindelige exempel skal jeg caste?

Uanset hvad er der ved at være kød nok på tillægsspørgsmålet til at lave et nyt spørgsmål, så jeg vi må hellere stoppe det her :)
Avatar billede arne_v Ekspert
11. april 2008 - 15:18 #10
Foerst en rettelse: ovenfor skrev jeg a[K][] - det skal vaere a[][K] ...

Jeg udtrykker mig muligvis uklart.

Her er et eksempel:

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

void f1(int a[][3])
{
    printf("%d\n", a[1][1]);
    return;
}

void f2(int **a)
{
    printf("%d\n", a[1][1]);
    return;
}

int main()
{
    int i,j;
    int a1[3][3];
    int **a2;
    a2  = (int **)malloc(3 * sizeof(int*));
    for(i = 0; i < 3; i++)
    {
        a2[i] = (int *)malloc(3 * sizeof(int));
        for(j = 0; j < 3; j++)
        {
            a1[i][j] = (i + j) * (i + j);
            a2[i][j] = (i + j) * (i + j);
        }
    }
    f1(a1);
    f2(a2);
    f1(a2); // <---- compiler warning + udskriver garbage
    f2(a1); // <---- compiler warning + crasher
    // missing free statements for a2
    return 0;
}
Avatar billede bertelbrander Novice
11. april 2008 - 20:14 #11
2D med vector:

#include <vector>
#include <stdio.h>

void f1(std::vector<std::vector<int> >  a)
{
  printf("%d\n", a[1][1]);
}

int main()
{
  int i,j;
  std::vector<std::vector <int > > a1(3, std::vector<int>(3));
  for(i = 0; i < 3; i++)
  {
      for(j = 0; j < 3; j++)
      {
          a1[i][j] = (i + j) * (i + j);
      }
  }
  f1(a1);
}

Jeg samler ikke på point.
Avatar billede hurra Novice
23. april 2008 - 22:00 #12
Undskyld jeg endnu en gang vender sent tilbage. hvis ikke bertelbrander vil ha points bliver du nødt til det arne_v, det har også gjort så rigeligt en indsat for det :)
Avatar billede arne_v Ekspert
23. april 2008 - 22:16 #13
svar
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



IT-JOB