问题
I'm working a sort of "restaurant" implementation in C with client-server. I am trying to send the following structure through a FIFO:
typedef struct {
int numtable; //table number to send answer
char timestamp[20]; //simple timestamp
int order[MENUSZ]; //array of int with dish IDs
} request;
About this struct, I basically send to the server the table number, to "build" the client FIFO name through a template, a timestamp, and order is a simple array filled with randomly chosen integers to "create" a sort of random menu request. With this setup I didn't have problems, using
write(server_fd, &request, sizeof(request))
I had problems when I wanted to transform the array order[MENUSZ] in a pointer, to make a dynamic array, like this:
typedef struct {
int numtable;
char timestamp[20];
int *order;
} request;
After changing the struct, I used the malloc function to allocate enough space for the array:
request->order = malloc(sizeof(int)*numclients+1);
The array is fullfilled correctly, but for some reason the server can't read from the FIFO after I added this pointer, by doing
read(server_fd, &request, sizeof(request));
I can't figure out why it doesn't work with this pointer. Am I doing something wrong?
回答1:
The array is fullfilled correctly, but for some reason the server can't read from the FIFO after I added this pointer, by doing
read(server_fd, &request, sizeof(request));
You are transferring your structure, which includes a pointer, and the value of the pointer will be transferred correctly, but it will not point to a valid address in the destination process, neither will there be memory allocated where the pointer points to.
Hence, you need to transfer the array separately and recreate the pointer in the destination process, something like:
read(server_fd, &request, sizeof(request));
/* allocate memory for request->order in the reader process */
request->order = malloc(sizeof(int)*numclients+1);
read(server_fd, request->order, sizeof(int)*numclients+1);
A yet better solution would be to also transfer the size of the array inside your structure.
On the sending side, you then need to send both, the structure and the array contents, something like
write(server_fd, &request, sizeof(request))
write(server_fd, request->order, sizeof(int)*numclients+1));
回答2:
It is because sizeof(request) no longer tells you the size of the combined structure. Try this
typedef struct {
int numtable;
char timestamp[20];
int order[1];
} request;
When you have a new request
int reqsize = sizeof(request) + sizeof(int) * numclients;
request* req = malloc(reqsize);
This allows you to use req->order[1] to req->order[numclients - 1]. When you send it, use
write(server_fd, reqsize, sizeof(int))
write(server_fd, req, reqsize)
When reading
read(server_fd, &reqsize, sizeof(int))
Then allocate the request before reading
request* req = malloc(reqsize)
read(server_fd, req, reqsize)
This technique uses "the chumminess of C" http://c-faq.com/struct/structhack.html, which, as far as I know, works on all implementations of C.
来源:https://stackoverflow.com/questions/26235345/write-complex-structures-on-a-fifo