Home > Blockchain >  How can I change the size of an array inside a function?
How can I change the size of an array inside a function?

Time:09-27

I recently toke a test about the C language and there was an exercise for which I would like to ask for your help since I didn't do well. The entire test revolved around two struct, "point" and "polygon": point had two double values for the x and y coordinate, and polygon had a int value for the number of point it has and a pointer to point for the list of its points.

typedef struct Punto{
double x;
double y;
}punto;
punto origine = {.x =0, .y =0};

typedef struct Poligono{
int numeroPunti;   //numbers of points
punto *punti;
}poligono;
poligono poligonoNullo = {.numeroPunti = 0, .punti = NULL};

I was then asked to create various functions to solve different tasks, one of witch was "aggiungiPunto" (add a point), that took a point and a polygon as input and added the given point to "polygon.punti". My attempt to create this function is the following

void aggiungipunto(punto p, poligono poli){

punto *prova;
prova = calloc(poli.numeroPunti  1, sizeof(punto));
for(int i=0; i<poli.numeroPunti;i  ){
    prova[i]=poli.punti[i];
}
poli.numeroPunti  ;
prova[poli.numeroPunti -1] = p;
poli.punti = &prova[0];
}

...witch didn't work: if I try to print the polygon inside the function (I have a "stampapoligono", printPolygon function that just list all the point and work correctly)i see that the code did what i wanted, but if i try to print the polygon inside my main function it is like nothing append. I belive it has to do with how a function in c takes a copy of the parameters, but i don't know how to work around it.

Just for more context here is the main function and how i tested:

int main(){

punto a = {.x =1, .y = 2};  
punto b = {.x = -1, .y = 2};

punto arraystatico[] = {origine, a, b}; 

poligono prova = poligonoNullo;
    prova.numeroPunti = 3;
    prova.punti = (punto *)calloc(prova.numeroPunti, sizeof(punto));

    for(int i=0;i < prova.numeroPunti ;i  ){
        prova.punti[i] = arraystatico[i];
    }

printf("Poligono iniziale:\n");
stampapoligono(prova);

punto c = {.x = 12, .y =3};
aggiungipunto(c, prova);

printf("Stampa esterna: \n");
stampapoligono(prova);
free(prova.punti);
return 0;
}

And here is how stampapoligono work

void stampapunto(punto p){
   printf("Coordinata x: %lf\tCoordinata y: %lf\n", p.x, p.y);
}

void stampapoligono(poligono poli){
   if (poli.numeroPunti ==0){
       printf("Il poligono non ha punti\n");
   }
   else{
      for(int i=0; i<poli.numeroPunti;i  ){
        stampapunto((poli.punti)[i]);
        printf("\n");
      }
   }
}

EDIT: I also tried this code which use realloc for aggiungipunto, but the result is the same:

void aggiungipunto(punto p, poligono poli){

punto *prova;
prova = calloc(poli.numeroPunti, sizeof(punto));
for(int i=0; i<poli.numeroPunti;i  ){
    prova[i]=poli.punti[i];
}

poli.punti = (punto *)realloc(poli.punti, poli.numeroPunti 1);
for(int i=0; i<poli.numeroPunti;i  ){
    poli.punti[i]=prova[i];
}

(poli.punti)[poli.numeroPunti] = p;
poli.numeroPunti  ;
}

CodePudding user response:

The function aggiungipunto shall access the original object prova by reference through a pointer to it. Otherwise the function will deal with a copy of the original object and change the copy. The original object will stay unchanged.

Also the function should report for the caller where a new point was added successfully.

And the first parameter should have the type poligono *.

So the function declaration should look like

int aggiungipunto( poligono *poli, punto p );

As the memory for points is allocated dynamically then you should use the function realloc.

The function can look like

int aggiungipunto( poligono *poli, punto p )
{
    punto *tmp = realloc( poli->punti, ( poli->numeroPunti   1 ) * sizeof( punto ) );

    int success = tmp != NULL;

    if ( success )
    {
        poli->punti = tmp;
        poli->punti[poli->numeroPunti  ] = p;
    }

    return success;
}

And the function is called like

aggiungipunto( &prova, c );

or

if ( !aggiungipunto( &prova, c ) )
{
    puts( "Error. No enough memory." );
}

Also the function stampapoligono should be declared like

void stampapoligono( const poligono *poli );

that is the original object should be passed by reference as a constant object through a pointer to it.

And my advice use English words for identifier names.

  • Related