Reputation: 590
So, I have some code and Valgrind seems to indicate that there is a memory leak present but I am not seeing it. The code in question is
void *run_client(void *n)
{
char recv_buffer[1024];
// This is random, but right now we will allocate 5120 bytes
// for the data coming from the instrument.
const int data_size = 5120;
int numbytes;
struct net_info *n_info;
n_info = (struct net_info *)malloc(sizeof(struct net_info));
n_info = (struct net_info *)n;
int clientfd;
clientfd = init_client(&n_info->cfg);
while (!*(n_info->flag))
{
// Clear the buffer every time...
memset(recv_buffer, 0, 1024);
if ((numbytes = recv(clientfd, recv_buffer, data_size - 1, 0)) == -1)
{
perror("recv");
exit(1);
}
if (recv_buffer[0] != '{' || recv_buffer[numbytes - 1] != '\n')
continue;
// remove last two bytes that are EOL indicators
numbytes -= 2;
recv_buffer[numbytes] = 0;
wclear(n_info->packet_win);
box(n_info->packet_win, 0, 0);
mvwprintw(n_info->packet_win, 1, 1, "%s", recv_buffer);
wrefresh(n_info->packet_win);
}
close(clientfd);
free(n_info);
return 0;
}
I am not sure if the details are necessary, but they are provided here so that you can understand the context. The function above is called from pthread_create
and listens on a specified port for data. The string data is then posted to an ncurses window (the code is preliminary and is currently just used for testing). The function exits when the main loop receives a request to exit and the flag in the while loop is set high.
The message from Valgrind is
==24037== 88 bytes in 1 blocks are definitely lost in loss record 14 of 55
==24037== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24037== by 0x401897: run_client (ncurses-cpc.c:60)
==24037== by 0x52906DA: start_thread (pthread_create.c:463)
==24037== by 0x57D588E: clone (clone.S:95)
and line 60 refers to n_info = (struct net_info *)malloc(sizeof(struct net_info));
. As you can see, before exiting the function requests a free
of the memory associated with that struct before exiting. Am I missing something? Why is Valgrind flagging this? (the message is posted after the heap summary message when valgrind is run with the option leak-check=yes
.)
Upvotes: 0
Views: 255
Reputation: 27924
n_info = (struct net_info *)malloc(sizeof(struct net_info));
You just allocated memory... and the very next line:
n_info = (struct net_info *)n;
You overwrite n_info
with n
, losing the reference to the memory you just allocated. The free()
by the end of the function is actually freeing n
, not the memory this malloc()
allocated.
Upvotes: 0
Reputation: 9213
From the comments it appears that you want to pass the input struct to the client thread. The leak appears because you allocate some memory and immediately discard the pointer to it.
No, you cannot just do -
struct net_info *n_info = n;
and free
the memory from the main loop, because that would lead to use after free bug.
What you need to do is transfer the ownership of this buffer to the thread. This basically means that from the point the thread starts, the input buffer is owned by the thread and it is the thread's responsibility to free
it.
You need to remove the new malloc
in the thread and just use the pointer directly. The pointer will be free
'd after the thread is done using it.
Also be careful that the main loop (or any other thread) should not be sharing the same buffer. This means that the main loop should malloc
a separate buffer for every thread it creates.
Upvotes: 2