I'm passing a dynamic array of structures to a function with the intent to write them into a binary file but after it's in the array the first values are the same (Arr+0) but the values after are garbage values when printing them out.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
int compGamesByTitle(const void * a, const void * b);
int compGamesByPrice(const void * a, const void * b);
typedef struct {
double price;
char title[25];
unsigned int popularity:3;
} game;
void writeBinary(game** Arr);
int compGamesByTitle(const void * a, const void * b)
{
game* p2first = *(game **)a;
game* p2second = *(game **)b;
return strcmp(p2first->title,p2second->title);
}
int compGamesByPrice(const void * a, const void * b)
{
game* p2first = *(game **)a;
game* p2second = *(game **)b;
return (p2first->price - p2second->price);
}
int main()
{
// create Array
int SIZE_OF_ARR = sizeof(game*)*6;
game** Arr = malloc(SIZE_OF_ARR);
double price[] = {22.79,0.01,14.99,0,7.79,64.96};
char* title[] = {"Opus Magnum","Minecraft", "Trainz","Code Combat", "Lemmings Revolution", "Warcraft"};
unsigned popularity[] = {1,4,2,3,3,1};
for (int i = 0; i < 6; i++)
{
Arr[i] = malloc(sizeof(game));
Arr[i]->price = price[i];
strcpy(Arr[i]->title,title[i]);
Arr[i]->popularity = popularity[i];
}
qsort(Arr,6,sizeof(game*),compGamesByTitle);
//print
printf("%s | %-20s | %s","Price", "Title", "Popularity\n");
printf("----------\n");
for (int i = 0; i < 6; i++)
{
printf("%5.2lf | %-20s | %2d\n",Arr[i]->price,Arr[i]->title,Arr[i]->popularity);
}
printf("----------\n");
qsort(Arr,6,sizeof(game*),compGamesByPrice);
//print
for (int i = 0; i < 6; i++)
{
printf("%5.2lf | %-20s | %2d\n",Arr[i]->price,Arr[i]->title,Arr[i]->popularity);
}
writeBinary(Arr);
for (int i = 0; i < 6; i++)
{
free(Arr[i]);
}
free(Arr);
return 0;
}
void writeBinary(game** Arr)
{
FILE* p2out = fopen("out.bin","wb");
for (int i = 0; i < 6;i++)
{
printf("%s \n",(*Arr+i)->title);
}
fclose(p2out);
}
I'm Still very new to C and am lost as the why the values are not same.
I'm passing a dynamic array of structures to a function with the intent to write them into a binary file but after it's in the array the first values are the same (Arr+0) but the values after are garbage values when printing them out.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
int compGamesByTitle(const void * a, const void * b);
int compGamesByPrice(const void * a, const void * b);
typedef struct {
double price;
char title[25];
unsigned int popularity:3;
} game;
void writeBinary(game** Arr);
int compGamesByTitle(const void * a, const void * b)
{
game* p2first = *(game **)a;
game* p2second = *(game **)b;
return strcmp(p2first->title,p2second->title);
}
int compGamesByPrice(const void * a, const void * b)
{
game* p2first = *(game **)a;
game* p2second = *(game **)b;
return (p2first->price - p2second->price);
}
int main()
{
// create Array
int SIZE_OF_ARR = sizeof(game*)*6;
game** Arr = malloc(SIZE_OF_ARR);
double price[] = {22.79,0.01,14.99,0,7.79,64.96};
char* title[] = {"Opus Magnum","Minecraft", "Trainz","Code Combat", "Lemmings Revolution", "Warcraft"};
unsigned popularity[] = {1,4,2,3,3,1};
for (int i = 0; i < 6; i++)
{
Arr[i] = malloc(sizeof(game));
Arr[i]->price = price[i];
strcpy(Arr[i]->title,title[i]);
Arr[i]->popularity = popularity[i];
}
qsort(Arr,6,sizeof(game*),compGamesByTitle);
//print
printf("%s | %-20s | %s","Price", "Title", "Popularity\n");
printf("----------\n");
for (int i = 0; i < 6; i++)
{
printf("%5.2lf | %-20s | %2d\n",Arr[i]->price,Arr[i]->title,Arr[i]->popularity);
}
printf("----------\n");
qsort(Arr,6,sizeof(game*),compGamesByPrice);
//print
for (int i = 0; i < 6; i++)
{
printf("%5.2lf | %-20s | %2d\n",Arr[i]->price,Arr[i]->title,Arr[i]->popularity);
}
writeBinary(Arr);
for (int i = 0; i < 6; i++)
{
free(Arr[i]);
}
free(Arr);
return 0;
}
void writeBinary(game** Arr)
{
FILE* p2out = fopen("out.bin","wb");
for (int i = 0; i < 6;i++)
{
printf("%s \n",(*Arr+i)->title);
}
fclose(p2out);
}
I'm Still very new to C and am lost as the why the values are not same.
Share Improve this question edited Mar 24 at 2:32 Raeden Nesbitt asked Mar 24 at 2:26 Raeden NesbittRaeden Nesbitt 213 bronze badges 2 |2 Answers
Reset to default 7The issue is in writeBinary
:
printf("%s \n",(*Arr+i)->title);
The pointer notation you used here isn't exactly the same as the array notation you used elsewhere. In other places you used Arr[i]
which is equivalent to *(Arr+i)
. That's not what you have here. For it to be the same you'd need (*(Arr+i))->title)
. Also, you're writing to stdout
instead of the file object you opened.
So the above should be:
fprintf(p2out,"%s \n",(*(Arr+i))->title);
Or more simply:
fprintf(p2out,"%s \n",Arr[i]->title);
On a side note, you don't actually have an array of structures but an array of pointers to structures. You can get rid of a level of indirection by creating an actual array of structs:
int SIZE_OF_ARR = sizeof(game)*6;
game *Arr = malloc(SIZE_OF_ARR);
...
for (int i = 0; i < 6; i++)
{
Arr[i].price = price[i];
strcpy(Arr[i].title,title[i]);
Arr[i].popularity = popularity[i];
}
...
int compGamesByTitle(const void * a, const void * b)
{
const game *p2first = a;
const game *p2second = b;
return strcmp(p2first->title,p2second->title);
}
Note that the above is not the complete set of necessary changes, but enough to give you an idea.
The problem is how you de-reference the pointers to print the game titles in void writeBinary(game** Arr)
. The line printf("%s \n",(*Arr+i)->title);
is first computing *Arr
, which is the same as Arr[0]
. The first iteration amounts to Arr[0]+0
, which doesn't corrupt the pointer to the first element. However, Arr[0]+1
and onward does corrupt the pointer. A correct and simpler way to iterate over the titles would be Arr[i]->title
(as you somehow DID do when freeing the games) or if you want to keep the arithmetic approach, then (*(Arr+i))->title
works too.
Also, just in case it's an overlook, you aren't actually writing anything to the file yet.
game* p2first = *(game **)a;
etc is wrong, should beconst game* p2first = *(const game **)a;
– Lundin Commented Mar 24 at 12:04