Reputation: 31
I know from previous C projects that ASAN tells me "heap-use-after-free" when I try to access to a pointer after the use offree() but in this case I don't even understand because i use free() at the end of the main and do nothing after.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define URL "URL"
#define API_KEY "KEY"
void add_parameter(char *query, char *key, char *value)
{
const size_t new_len = strlen(query) + strlen(key) + strlen(value) + 3;
query = realloc(query, new_len * sizeof(char));
if (query)
{
strcat(query, "?");
strcat(query, key);
strcat(query, "=");
strcat(query, value);
query[new_len - 1] = '\0';
printf("%s\n", query);
}
}
int main()
{
char *query = malloc((strlen(URL) + 1) * sizeof(char));
memcpy(query, URL, sizeof(URL));
add_parameter(query, "api_key", API_KEY);
printf("%s\n", query);
free(query);
return 0;
}
Thanks for your help
Upvotes: 1
Views: 898
Reputation: 311058
For starters the pointer query
is passed to the function add_parameter
by value
add_parameter(query, "api_key", API_KEY);
It means that the function deals with a copy of the value of the pointer query
within the function.
Changing the copy does not reflect on the original pointer query
. The original pointer query
passed to the function by value stays unchanged.
You need to pass the pointer by reference.
Passing by reference in C means passing an object indirectly through a pointer to it. Dereferencing the pointer you will have a direct access to the original object.
In this case the function will be declared like
int add_parameter(char **query, const char *key, const char *value);
(as the strings pointed to by the parameters key
and value
are not changed within the function the parameters should be declared with the qualifier const
) and within the function you have to write
int add_parameter( char **query, const char *key, const char *value )
{
const size_t new_len = strlen( query ) + strlen( key ) + strlen( value ) + 3;
char *tmp = realloc( query, new_len * sizeof( char ) );
int success = tmp != NULL;
if ( success )
{
strcat( rmp, "?" );
strcat( tmp, key );
strcat( tmp, "=" );
strcat( tmp, value );
printf("%s\n", tmp);
*query = tmp;
}
return success;
}
This statement within the function
tmp[new_len - 1] = '\0';
is redundant. So it is removed
Pay attention to that realloc
can return a null-pointer. In this case if not to use the intermediate variable tmp
the early allocated memory can be lost.
The function can be called like
add_parameter( &query, "api_key", API_KEY);
or
if ( add_parameter( &query, "api_key", API_KEY) )
{
//...
}
else
{
//...
}
Upvotes: 4
Reputation: 60017
The following line can cause a problem
query = realloc(query, new_len * sizeof(char));
As the value of query
could change. It, main
. it is unaware of this change. Pass the updated version of query
back to main
.
Upvotes: 3