Reputation: 14199
I'm new to c and attempting socket programming. I have a question about pointers.
Say I have a setup like this:
int main() {
... // some code
int numbytes = receive(i);
}
int receive(int num) {
... // some code
msgLength = ... // some code
char msgWithLength[4 + msgLength];
int n = getMsg(clientSocket, msgWithLength, 4 + msgLength);
char * msg = unpack(msgWithLength, 4);
return n;
}
char * unpack(char *msgWithHeader, int headerSize) {
char *msg = ... // some code to remove header from msgWithHeader
return msg;
}
What I want is to access msg in in main. I don't want recieve to return msg though, I want it to return an int. Also, in main, I don't know the size of msg.
Ideally I'd have something like
int main() {
char * msg;
int numbytes = receive(i, msg);
// And be able to access msg here
}
But this doesn't work. I guess my question is related to pointers and passing by reference. Any ideas on how to get this to work?
Upvotes: 0
Views: 102
Reputation: 7061
You have to pass a pointer to your variable in C in order to "pass by reference". To get data into a char * variable from a function that you call, the function has to take the address of your char *. The syntax for the address of a character pointer looks like: char** (one asterisk to represent a pointer, and the other asterisk to show that the pointer is pointing to a "char *", a character pointer variable). The value given to the "char * *" parameter is the address of your char * variable : &msg. Then inside the function you dereference the char ** variable - *address_of_msg - to assign to the msg variable that is external to the function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int receive(int a, char **address_of_msg)
{
*address_of_msg = malloc(200);
strcpy(*msg,"modified in subroutine");
return 10;
}
int main(void)
{
char *msg;
int return_value;
return_value = receive(20,&msg);
printf("return value: %d msg: %s\n",return_value,msg);
}
Upvotes: 1
Reputation: 1835
It's perfectly normal to do something like that with pointers. But it can be a bit tricky. If the function does the memory allocation, you will have to pass a pointer to a pointer as an argument, which is possible, but not very common. The Apache Portable Runtime library makes use of this technique.
It is more common to pass a pointer to a buffer and the size of the buffer as arguments, like so:
int your_read(int fd, char *buf, size_t len) {
return read(fd, but, len);
}
// called using e.g.:
char the_buffer[1024];
your_read(0, the_buffer, sizeof(the_buffer))
If you do want to do something similar to what I described first, it would be:
int create_object(struct example **e) {
*e = malloc(sizeof(**e));
if (*e == NULL)
return -1;
(*e)->name = "example";
return 0;
}
// called using:
struct example *the_example;
create_object(&example);
Upvotes: 1