-1

I'm trying to populate struct values using system calls. My initial effort follows. However i get junk values from the print statement.

int fd;
int nbytes;
struct message {
  char *from;
  char *to;
  int size;
};
struct message m1={"me","you",10};
struct message m2;

fd=creat("structfile",0644);
nbytes=write(fd,&m1,sizeof(m1));
read(fd,&m2,nbytes);

printf("%s %s %d",m2.from,m2.to,m2.size);

Is there another way to do this? (I'm thinking of the way that structures like hostent and dirent are filled up directly by making calls to gethostbyname and readdir respectively)

user3818219
  • 43
  • 1
  • 4

2 Answers2

1

Problem 1:

Where is fd intialized?

Problem 2:

The line

nbytes=write(fd,&m1,sizeof(m1));

write the numerical values of the pointers m1.from and m1.to. It does not write the strings they point to.

If you want to write the contents of m1, you have to serialize the contents of m1.from and m1.to. There are libraries for that purpose. You can see some references from How to serialize data in C.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Sorry. Corrected fd initialization. – user3818219 Jul 30 '14 at 04:13
  • @user3818219, In addition to the problem of using `write` for an object of type `struct message`, you also have the problem that `fd` oints to the end of the file after the write. There is nothing for `read` to read. – R Sahu Jul 30 '14 at 04:19
  • 1
    @RSahu fd doesn't really point anywhere; that could be confusing language to someone new to C. it is basically a constant integer that references the `open`ed file ... you have to use `lseek` (or similar) to tell the kernel to move around the *unbuffered* file (file descriptor as opposed to FILE*) ... one of the easiest ways to transmit strings is a size:values method such as 5hello5world or "string" `write(fd,strlen(s),sizeof(size_t));write(fd,s,strlen(s));` and then on the other end `read(fd,len,sizeof(size_t));read(fd,string,len);...` Note: integers are endian dependent – technosaurus Jul 30 '14 at 06:24
  • @technosaurus: the *other* easy way to transmit strings is using fixed-length strings - [`dirent`](http://stackoverflow.com/questions/12991334/members-of-dirent-structure) does. This removes the need for allocating and freeing memory for each string. – Jongware Jul 30 '14 at 08:25
1

Problem 3, your struct contains character pointers:

struct message {
  char *from;
  char *to;
  int size;
};

Your sizeof(m1) writes the size of 2 (char *) pointers and an (int). The data pointed to by from and to can vary based on the size of the string. Reading sizeof(m1) does not take into account the size of the strings pointed to.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85