Reputation: 13
I want to read a chunk of data from a binary file into a buffer and then place pointers at different locations in the buffer to store the structs in the buffer. However, I get the wrong data back when I try this method, possibly due to where I'm placing the pointers.
Note: readEntry and writeThis are just low level read() and write() with error trapping built in. readEntry terminates the program once it reaches the end of the file.
#define BUF 64
struct my_struct
{
int num;
};
my_struct and definition of BUF
int i;
char buffer[BUF];
struct my_struct *m = (struct my_struct *) malloc(sizeof(struct my_struct));
for(i=0; i<4; i++)
{
m->num = i;
printf("Initializing m->num to %d\n", m->num);
writeThis(fd, &m, sizeof(struct my_struct));
}
lseek(fd, 0, SEEK_SET);
while(1)
{
printf("Read\n");
readEntry(fd, buffer, (sizeof(struct my_struct)*4));
m = (struct my_struct *) buffer;
printf("num = %d\n", m->num);
m = (struct my_struct *) buffer+(sizeof(m));
printf("num = %d\n", m->num);
m = (struct my_struct *) buffer+((sizeof(m)*2));
printf("num = %d\n", m->num);
m = (struct my_struct *) buffer+((sizeof(m)*3));
printf("num = %d\n", m->num);
}
return 0;
writeThis()
void writeThis(int fd, void *buffer, int writeAmt)
{
if (write(fd, buffer, writeAmt) != writeAmt)
{
fprintf(stderr, "Error writing\n");
exit(-1);
}
}
readEntry()
void readEntry(int fd, void *buffer, int writeAmt)
{
if (read(fd, buffer, writeAmt) != writeAmt)
{
printf("Finished reading\n");
free(buffer);
exit(0);
}
}
The return I get for the sizeof(struct my_struct) is 4
Output:
Initializing m->num to 0
Initializing m->num to 1
Initializing m->num to 2
Initializing m->num to 3
Read
num = 134524936
num = -1208081680
num = -1209552416
num = 1111804576
Read
Finished reading
hexdump
00000000 10 b4 04 08 10 b4 04 08 10 b4 04 08 10 b4 04 08 |................|
00000010
Upvotes: 1
Views: 122
Reputation: 153498
Some cleaned-up untested code - see comment for fixes to the problems. The 2 big ones are & when not needed and pointer arithmetic.
#define BUF 64
struct my_struct {
int num;
};
int i;
// Suggest `malloc()` rather than `char buffer[BUF]`.
// The issues is _alignment_, perhaps that is new for you.
char *buffer = malloc(BUF);
// Cast not needed. Better to use size of variable, than sizeof type.
// Think how easy this is to maintain code should `m` take on a new type.
// struct my_struct *m = (struct my_struct *) malloc(sizeof(struct my_struct));
struct my_struct *m = malloc(sizeof *m);
for(i=0; i<4; i++) {
m->num = i;
printf("Initializing m->num to %d\n", m->num);
// & not needed here. `m` is the pointer to the place to read data
// writeThis(fd, &m, sizeof(struct my_struct));
// Use size of variable
writeThis(fd, m, sizeof *m);
}
lseek(fd, 0, SEEK_SET);
while(1)
{
printf("Read\n");
// Again, use sizeof the variable, rather than size of type
//readEntry(fd, buffer, (sizeof(struct my_struct)*4));
readEntry(fd, buffer, sizeof *m *4);
m = (struct my_struct *) buffer;
printf("num = %d\n", m->num);
// do not cast and then add to char *
// add and then cast
// m = (struct my_struct *) buffer+(sizeof(m));
m = (struct my_struct *) (buffer+(sizeof(*m));
// OR, add after the cast, but only add 1
m = (struct my_struct *) buffer + 1;
printf("num = %d\n", m->num);
m = (struct my_struct *) buffer+2;
printf("num = %d\n", m->num);
m = (struct my_struct *) buffer+3;
printf("num = %d\n", m->num);
// You could have an infinite loop here, need a reason to exit
}
free(buf);
return 0;
Robust code would check the return results from malloc()
before using them
Upvotes: 1