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.

+3


source to share


4 answers


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.

+5


source


You can only free

pointer that is the result of malloc

or realloc

. You cannot reduce the size of the selection by free

ing at an arbitrary offset from it. But you can realloc

it at a smaller size: realloc(*str, lsi)

.



+2


source


one way is to create a new line and use only the space you need and copy the content into that. now you can free the previous one. I will use this realloc () not allowed (sometimes in homework)

another way is realloc () like others.

+1


source


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

0


source







All Articles