0

How can I free a string up to a certain point? For example if I have:

char *s = (char *)malloc(sizeof(char) * 21);
s[20] = '\0';
int i = 0;
while (i < 21)
{
    s[i] = i + 'a';
    i++;
}

And then I cut off the string at some point and store that half:

*(s + 10) = '\0';
char *m = s + 11;

Is there a way to free s up to s + 10 or the first \0?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

2 Answers2

4

Since s has been allocated by the system, you can perform a realloc on it to shorten the size:

s = realloc(s, 11);

But you cannot free the start of an allocated zone without freeing the rest, that you cannot. Use memmove & realloc to shift the data and reduce size afterwards.

Attempting to free a pointer which hasn't been allocated, or an allocated pointer plus an offset results in undefined behaviour.

You could do (as you suggested yourself, but with problems fixed :)):

char *c = strdup(s + 10);
free(s);
s = c;

so now s points to the end of the string.

alternative without strdup but using standard functions only (with the risk of forgetting the null-termination char):

char *c = malloc(strlen(s) - 10 + 1);
strcpy(c,s + 10);
free(s);
s = c;

and the memmove solution I was hinting about at first (avoids to allocate/free but offset/size is trickier to compute):

int offset = 10;
int size = strlen(s) - offset;
memmove(s,s+offset,size);
s[size]='\0';  // null-terminate
s = realloc(s,size+1);  // adjust size after null-termination
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
2

Is there a way to free s up to s + 10 or the first \0?

No. Not in the standard library at least.

There's realloc but it isn't guaranteed to "free s up to s + 10 or the first \0".

Emil Laine
  • 41,598
  • 9
  • 101
  • 157