1

When I allocate an array using malloc, is there a way to only free the first element(s) of the array?

A small example:

#include <stdlib.h>
#include <string.h>

int main() {
    char * a = malloc(sizeof(char) * 8);
    strcpy(a, "foo bar");

    // How I would have to do this.
    char * b = malloc(sizeof(char) * 7);
    strcpy(b, a+1);


    free(a);
    free(b);
}

Is there a way to free just the first char of a, so that I can use the rest of the string using a+1?

Ward Segers
  • 519
  • 5
  • 17
  • 7
    No you cant free only one byte of array. You can free only pointer returned from `malloc`, which points on the first byte of allocated array, and as well, it will free all the allocated array of bytes. Anyway you can realloc it to size you want, which can be more or less bytes then actuall size. – kocica Aug 18 '17 at 13:52
  • 1
    More importantly, why???? – Sourav Ghosh Aug 18 '17 at 13:54
  • Take a look at [this](https://stackoverflow.com/a/27876929/2173917) Dupe??? – Sourav Ghosh Aug 18 '17 at 13:54
  • 3
    You could work with another pointer, with `char *b = a + 1;` and later on, you just `free(a);` – Weather Vane Aug 18 '17 at 14:05
  • @WeatherVane I know. I was just wondering if that would be possible. – Ward Segers Aug 18 '17 at 14:08

2 Answers2

5

If you want to remove the first character of a, you could use memmove() to move the remainder of the characters in the string to the left by 1, and you could use realloc() to shrink the allocation if desired:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char * a = malloc(sizeof(char) * 8);
    strcpy(a, "foo bar");

    puts(a);

    size_t rest = strlen(a);

    memmove(a, a+1, rest);

    /* If you must reallocate */
    char *temp = realloc(a, rest);
    if (temp == NULL) {
        perror("Unable to reallocate");
        exit(EXIT_FAILURE);
    }
    a = temp;

    puts(a);

    free(a);

    return 0;
}

Update

@chux has made a couple of good points in the comments.

First, instead of exiting on a failure in realloc(), it may be better to simply continue without reassigning temp to a; after all, a does point to the expected string anyway, the allocated memory would just be a little larger than necessary.

Second, if the input string is empty, then rest will be 0. This leads to problems with realloc(a, rest). One solution would be to check for rest == 0 before modifying the string pointed to by a.

Here is a slightly more general version of the above code that incorporates these suggestions:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char *s = "foo bar";
    char *a = malloc(sizeof *a * (strlen(s) + 1));
    strcpy(a, s);

    puts(a);

    size_t rest = strlen(a);

    /* Don't do anything if a is an empty string */
    if (rest) {
        memmove(a, a+1, rest);

        /* If you must reallocate */
        char *temp = realloc(a, rest);
        if (temp) {
            a = temp;
        }
    }

    puts(a);

    free(a);

    return 0;
}
ad absurdum
  • 19,498
  • 5
  • 37
  • 60
0

Is there a way to free just the first char of a

No. You can not free the first character of a because it is of char type. Only pointer returned by malloc family function can be freed. You can do this though.

char * a = malloc(sizeof(char) * 8);
strcpy(a, "foo bar");
char * b = malloc(strlen(a));
strcpy(b, a+1);
free(a);
haccks
  • 104,019
  • 25
  • 176
  • 264