Can I free only part of the string?
I fill in a character string and double its size from time to time.
When I am done, I would like to free unused memory.
void fun (char **str, size_t *len) {
size_t lsi; //last_significant_index
//filling up the str and reallocating from time to time.
//*len is storing the total size of allocated memory at this point
// idea #1
free((*str)[lsi + 1]);
// idea #2
for(size_t i = lsi + 1; i < *len; i++) {
free(&(*str)[i]);
}
}
None of these ideas work, however
Is it possible to do this? If so, how?
Details:
I use this function to reallocate strings:
static void increase_list_size(char **list, size_t *list_len)
{
size_t new_list_size = (*list_len + 1) * 2; // I am not allocating my list at the declaration, so *list_len initially equals 0.
char *new_list = malloc(sizeof(char) * new_list_size);
for (size_t i = 0; i < *list_len; i++)
{
new_list[i] = (*list)[i];
}
if (list != NULL) // I don't want to free an empty list (it wasn't allocated at the declaration!
{
free(*list);
}
(*list) = new_list;
*list_len = new_list_size;
}
As you can see, I allocate twice as much memory each time - so I wanted to free unused memory at the end.
I thought there was some tricky way to do this since I felt like you can use free()
to free the entire block of memory.
source to share
No, you can only have pointers free()
that were returned malloc()
.
You want to use realloc()
to resize the allocated memory to a smaller (as well as larger) size. The contents of the array will be saved.
Example:
#include <stdlib.h>
int main() {
char *str = malloc(100);
...
str = realloc(str, 50);
...
free(str);
}
Remember to check the return value realloc()
(as well as the value malloc()
) to ensure that the distribution (re) didn't work.
source to share
You can use the standard C function realloc
declared in the header<stdlib.h>
for example
char *s = malloc( 100 );
strcpy( s, "Hello world" );
char *p = realloc( s, strlen( s ) + 1 );
if ( p != NULL ) s = p;
Here is a demo program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( void )
{
char *s = malloc( 100 );
strcpy( s, "Hello world" );
char *p = realloc( s, strlen( s ) + 1 );
if ( p != NULL ) s = p;
puts( s );
free( s );
return 0;
}
Program output
Hello world
Or, if you want to write a separate function, then it might look like this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void resize( char **s, size_t n )
{
char *p = realloc( *s, n );
if ( p != NULL ) *s = p;
}
int main( void )
{
char *s = malloc( 100 );
strcpy( s, "Hello world" );
resize( &s, strlen( s ) + 1 );
puts( s );
free( s );
return 0;
}
Also you can use POSIX function strdup
source to share