Janic1
Janic1

Reputation: 11

Resize (Decrease) a char array using realloc and check for success

I've tried to initialize a dynamic char array, that decreases, if the string input from the user is smaller.

The problem is: I've got no idea, if the program is actually doing that? I get no error message and the right output, but is the unused memory really freed?

char *input=(char*)malloc(100);
gets(input);
int a = strlen(input);
input = realloc(input, a+1);

Upvotes: 0

Views: 479

Answers (3)

Sourav Ghosh
Sourav Ghosh

Reputation: 134356

Usually, the only way to check the success of the allocator functions would be to check for the returned pointer by the realloc() call against a NULL pointer. If the returned pointer is not NULL, you can be assured that the call is success.

Following the lines, the approach like

  pointer = realloc (pointer, newValue);

is problematic, as in case of realloc() failure, quoting from C11, chapter §7.22.3.5,

[....] If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

and

The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.

Thus, the returned null-pointer will overwrite the previous valid memory address and you'll lose the access and leak memory. The safe course of action is to

  type tempPOinter = NULL;
  tempPOinter = realloc(oldPointer, newSize);
  if (tempPOinter) {
      oldPointer = tempPOinter;
  }
  else {
     printf("Failure in realloc!!"); 
     free(oldPointer);
     return -1;
  }

Upvotes: 1

mamooot
mamooot

Reputation: 7

I suggest you to change your algorithm. In C, you can reserve a big-enough buffer on the stack, then after reading the input, allocate a permanent buffer on the heap:

#define BIG_ENOUGH 4096
char *get_line(FILE *fp)

{
    char buf[BIG_ENOUGH] = "";

    return fgets(buf, BIG_ENOUGH - 1, fp) ? strdup(buf) : NULL;
}

Upvotes: 0

Swordfish
Swordfish

Reputation: 13134

Don't cast the result of *alloc() in C. Its not needed, only adds clutter to the code and in the worst case covers up errors like forgetting to #inlude <stdlib.h> for *alloc().

The line

input = realloc(input, a+1);

is problematic because you lose the previous pointer value if realloc() fails and returns NULL. Better:

char *new_input = realloc(input, a+1);
if(!new_input) {
    free(input);
    // print some error message
    return EXIT_FAILURE;
}

// everything fine:
input = new_input;

// use input

free(input);

PS: Also, as others have pointed out in the comments: Remove gets() from your vocabulary. Pretend it never existed. Use fgets() instead.

Upvotes: 3

Related Questions