I'm passing a buffer (char*) to a function in C.
Inside the function, I'm allocating memory for the buffer and appending a string (response from a dummy server). When printed inside the function, the string is being displayed as sent from the server.
When trying to read the buffer from outside the function, I'm not getting the result I need:
a. // char* server_message; // does not work, error:: Segmentation fault (core dumped)
b. // char* server_message = calloc((BUFFER_SIZE) + 1, sizeof(char)); // does not work, no error generated, printf of server_message below prints an empty value:: ==> server_message:: || ||
c. char* server_message = calloc((1000 * BUFFER_SIZE) + 1, sizeof(char)); // allocating more than needed memory works:: ==> server_message:: || 2016-03-08 12:20:13 hello there ||
I don't like option c at all, because I'm allocating more memory than I need. BUFFER_SIZE is currently set to 10 for testing purposes.
Here is the calling part::
write_to_server(client_socket, message, server_message);
free(message);
printf("\n\n==> server_message:: || %s ||\n\n", server_message);
if (server_message != NULL)
free(server_message);
Here is the write_to_server function code::
void write_to_server(int file_descriptor, char* message, char* server_message)
{
char* msg = strcat(message, "\n");
int n_bytes = write(file_descriptor, msg, strlen(msg) + 1);
if (n_bytes <= 0)
{
perror("write");
exit(EXIT_FAILURE);
}
if (DEBUG_MODE)
printf("\nsuccessfully written %d bytes to server:: %s", n_bytes, msg);
// char* message_back = calloc(BUFFER_SIZE + 1, sizeof(char));
if (server_message == NULL)
{
server_message = calloc(BUFFER_SIZE + 1, sizeof(char));
}
if (server_message == NULL)
{
perror("Could not allocate memory for server_message");
exit(EXIT_FAILURE);
}
char* tmp_message_back = calloc(BUFFER_SIZE + 1, sizeof(char));
if (tmp_message_back == NULL)
{
if (DEBUG_MODE)
perror("Could not allocate memory for tmp_message_back");
exit(EXIT_FAILURE);
}
int n_read = 0;
int n_total_read = 0;
while ((n_read = read(file_descriptor, tmp_message_back, BUFFER_SIZE)) > 0)
{
n_total_read += n_read;
tmp_message_back[n_read] = '\0';
/*
char* strcat(char* destination, const char* source);
Appends a copy of the source string to the destination string.
The terminating null character in destination is overwritten by the first character of source,
and a null-character is included at the end of the new string formed by the concatenation of both in destination.
*/
server_message = strcat(server_message, tmp_message_back);
// void* realloc(void* ptr, size_t size);
/*
char* new_message_back = realloc(server_message, n_total_read + (BUFFER_SIZE * sizeof(char)));
if (new_message_back == NULL)
{
perror("Could not allocate memory for server_message while receiving bytes from server");
free(tmp_message_back);
return;
}
server_message = new_message_back;
*/
server_message = realloc(server_message, n_total_read + (BUFFER_SIZE * sizeof(char)));
server_message[n_total_read] = '\0';
if (DEBUG_MODE)
printf("\nread %d (%d in total), size:: %zu ===> | %s |\t| %s |\n", n_read, n_total_read, strlen(server_message), server_message, tmp_message_back);
}
server_message = realloc(server_message, n_total_read);
if (DEBUG_MODE)
{
printf("\n\n\n\n-- read %d in total, size:: %zu\n", n_total_read, strlen(server_message));
printf("\n\nserver_message:: %s\n\n", server_message);
}
free(tmp_message_back);
// free(message_back);
}
In C parameters are passed by value.
Basically you are doing this expecting the output isHello world!
:
void Test(char *ptr)
{
ptr = malloc(100); // this modifies ptr but not
// somepointer in the main function
strcpy(ptr, "Hello world!");
}
int main()
{
char *somepointer; // somepointer is not initialized and contains
// an indetermined value
Test(somepointer);
// here the value of somepointer has not changed
printf("%s", somepointer); // here you try to printf a char pointer
// that points to an idetermined location
return 0;
}
This is undefined behaviour and will most likely print garbage or crash.
What you need is this:
void Test(char **ptr)
{
*ptr = malloc(100);
strcpy(*ptr, "Hello world!");
}
int main()
{
char *somepointer;
Test(&somepointer); // pass the pointer to sompointer to Test
printf("%s", somepointer); // now somepointer points to the memory
// mallocd in Test
return 0;
}