0

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);
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Janic1
  • 11
  • 6
    Never ***ever*** use `gets`. It's [a dangerous function](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) that have even been removed from the C standard. – Some programmer dude Nov 13 '18 at 11:09
  • Use a debugger...to find out. – Sourav Ghosh Nov 13 '18 at 11:11
  • 2
    As for your problem, it *might* be reallocated. Or it might not. You don't know, and it's not really relevant. However there's a very easy way to find out: If `realloc` returning the same pointer as `malloc` did? And related to that, don't forget to *always* assign the result of `realloc` to a new pointer, or you lose the original pointer if `realloc` returns `NULL`. – Some programmer dude Nov 13 '18 at 11:11
  • 1
    Well yes, the unused memory has been freed but you dont get to see it. – machine_1 Nov 13 '18 at 11:12
  • Why are you expecting an error message? – Jabberwocky Nov 13 '18 at 11:15

3 Answers3

3

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.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • "Don't cast" - actually, oppinions about [differ](https://stackoverflow.com/a/14879184/1312382) - maybe a minority, but a notable one... My personal recommendation to the topic: read and make up your own mind (or follow the rules of the project, if there are). – Aconcagua Nov 13 '18 at 11:31
1

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;
  }
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

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;
}
mamooot
  • 7
  • 2
  • @machine_1: strdup() returns a pointer to an **allocates region of memory on the heap**, initialized with 'buf' (in our example). This code segment is just a hint for another algo. Regards... – mamooot Nov 13 '18 at 12:00
  • Oops, on my android phone I did not see the strdup call. Sorry. – machine_1 Nov 13 '18 at 12:02