I'm initializing the values of an array pointer inside a function by allocating it first, and then allocating its content (struct pointers) iterating over the reading of values.
Those are the definition of Richiesta and the content of the initializing function:
typedef struct richiesta {
int durata;
} *Richiesta;
void leggiParametri(Richiesta **richieste, int *n){
// size
scanf("%d", n);
*richieste = calloc(*n, sizeof(struct richiesta));
//printf("Inside loop:\n");
for(int i = 0; i < *n; i ){
Richiesta richiesta = malloc(sizeof(struct richiesta));
printf("%d\t", richiesta);
scanf("%d", &richiesta->durata);
(*richieste)[i] = richiesta;
printf("%d: %d\n", i, (*richieste)[i]->durata);
}
printf("Outside loop:\n");
printf("%d: %d\n", 0, (*richieste)[0]->durata);
printf("%d: %d\n", 1, (*richieste)[1]->durata);
}
The main body:
Richiesta *richieste = NULL;
int n = -1;
leggiParametri(&richieste, &n);
Giving the following input:
6
4
7
3
8
1
5
15
the output is:
-858131760 0: 4
-858127616 1: 7
-858127584 2: 3
-858127552 3: 8
-858127520 4: 1
-858127488 5: 5
Outside loop:
0: -858127520
1: 7
The problem occurs only for the first element of the array, in the for loop it contains the correct value read, while outside it contains that particular value, which corresponds to the address pointed to by the 5th element (printed as an integer).
(the same thing happens even printing the array content inside either an other function or main body)
- What causes the problem?
- Why does it point to that specific value?
- And is there any way to make it work?
Also, uncommenting the line of printf("Inside loop:\n"); returns a segmentation fault when printing.
CodePudding user response:
You did not allocate an array of pointers in this statement
*richieste = calloc(*n, sizeof(struct richiesta));
where the type specifier Richiesta as you wrote in a comment is an alias for the type struct richiesta. You allocated an array of structures.
So this assignment
(*richieste)[i] = richiesta;
does not make a sense.
It seems you mean
*richieste = calloc(*n, sizeof( Richiesta ));
Pay attention to that using a typedef for a pointer like this
typedef struct richiesta *Richiesta;
is a bad idea. This only confuses readers of the code.
CodePudding user response:
You were caught by a mix of structs and pointer to structs. Allocating an array of pointers to later allocate a struct per element is an anti-pattern and the correct way is indeed to directly allocate an array of structs. But then the code will become:
void leggiParametri(Richiesta* richieste, int* n, int* t) {
// dimensione
scanf("%d", n);
//printf("%d\n", *n);
*richieste = calloc(*n, sizeof(struct richiesta));
// richieste
//printf("Inside loop:\n");
for (int i = 0; i < *n; i ) {
Richiesta richiesta = *richieste i;
printf("%p\t", richiesta);
scanf("%d", &(richiesta->durata));
printf("%d: %d\n", i, (*richieste)[i].durata);
}
printf("Outside loop:\n");
printf("%d: %d\n", 0, (*richieste)[0].durata);
printf("%d: %d\n", 1, (*richieste)[1].durata);
// tempo
scanf("%d", t);
//printf("%d\n", *t);
}
You could then call the function that way:
Richiesta richieste = NULL;
int n, t;
leggiParametri(&richieste, &n, &t);
// other processing....
free(richieste);
CodePudding user response:
- Do not hide pointer behind
typedefs. It is a vera bad practice. - Do not use side effects without special need. You only allocate 1D array and you should use the function return value.
typedef struct Richiesta
{
int durata;
} Richiesta;
Richiesta *leggiParametri(int *n)
{
Richiesta *richiesta = NULL;
// size
if(scanf("%d", n) != 1) { /*error handling */};
if(n >= 0)
{
richiesta = calloc(*n, sizeof(*richiesta));
//printf("Inside loop:\n");
for(int i = 0; i < *n; i )
{
scanf("%d", &richiesta[i].durata);
printf("%d: %d\n", i, richiesta[i].durata);
}
printf("Outside loop:\n");
printf("%d: %d\n", 0, richiesta[0].durata);
printf("%d: %d\n", 1, richiesta[1].durata);
}
return richiesta;
}
``
