2

I've been trying to be more "memory-aware" in my C programming when I found out about the malloc method and similar memory management methods. However, when I tried to use realloc to allocate as little memory as possible to a char* instance in my program, I found that it wasn't holding as much data as I thought it would.

Here is my code:

int foo(char * arg){
    if(condition){
        //code here
    }else if(other_condition){
        char * cmd = malloc(5);
        fgets(cmd,sizeof(cmd),stdin);
        //more code here
        if(another_condition){
            //more code
            cmd = realloc(cmd,new_size) //once in this if block, but also once in another block
            fgets(cmd,sizeof(cmd),stdin);
            //more code
        }
        //more else-if blocks here
        free(cmd)
    }
    //more else-if blocks here
}

To be specific, in the above code snippet, new_size was 255, although it has been set to other sizes in other places. The problem is that when I run the program I only get 7 letters of my input.

Example output:

...
Enter filename: document1
Loading file "documen"
Load failed
...
(here the next time fgets is called it fails because "t1" is not valid input for the program)

I understand that it's receiving "t1" because I'm not clearing the input buffer, but what I want to solve is the fact that I'm only receiving the first 7 characters of the input. If I call sizeof(cmd) in the middle, it tells me that the memory occupied by cmd is 8. I also tried allocating the memory using char * cmd = malloc(5 * sizeof(char)) and cmd = realloc(cmd,255 * sizeof(char)) but it didn't solve the problem. I should probably mention that if I declare the variable using the char cmd[255] syntax and I don't call malloc, realloc, or free anywhere this problem no longer comes up.

Arc676
  • 4,445
  • 3
  • 28
  • 44
  • If you're on a platform that supports [GNU `getline()`](https://www.gnu.org/software/libc/manual/html_node/Line-Input.html) you might want to consider using it - it helps manage the dynamic allocation of the buffer for lines of input (though you will still need a variable to track the size). – Michael Burr Oct 03 '14 at 05:11
  • 1
    http://stackoverflow.com/questions/2478240/how-i-return-the-size-of-the-pointer-that-i-have-allocate-with-malloc – M.M Oct 03 '14 at 05:11

1 Answers1

2
fgets(cmd,sizeof(cmd),stdin);

Here cmd is a char* instead of a char[]. Thus, its size is always the size of a pointer, instead of the array size.

You should keep track of the chunk size allocated by yourself.

timrau
  • 22,578
  • 4
  • 51
  • 64
  • Is there a way to use `malloc` with `char[]`? If I declare the variable with `char cmd[] = malloc(255)` it says the "array initializer must be an initializer list or a string literal". Are there other solutions? Is the only way to free `cmd`'s memory to wait for it to go out of scope? – Arc676 Oct 03 '14 at 04:43
  • No. The general rule of thumb is that you should explicitly know (and usually keep - in a variable or a field) the size of `malloc`-ed data. You might consider using flexible array members like in [this answer](http://stackoverflow.com/a/23433573/841108) – Basile Starynkevitch Oct 03 '14 at 04:49
  • @Arc676 `char cmd[255];` instead of `char cmd[] = malloc(255);` – M.M Oct 03 '14 at 04:57
  • 1
    @MattMcNabb Is that the only way? Using your method would mean that `cmd` will automatically be released when it goes out of scope, but I would have no control over when it is released right? – Arc676 Oct 03 '14 at 05:01
  • Yes that's right. If you want control over when it is freed then use the malloc version. – M.M Oct 03 '14 at 05:03
  • Using the `malloc` version is what is causing this problem. – Arc676 Oct 03 '14 at 05:17
  • So you have two options, and if you want the option that includes the flexibility you get by using `malloc()` you'll have to track the allocation size yourself. – Michael Burr Oct 03 '14 at 05:20
  • But how do I allocate to `char[]` using `malloc`? – Arc676 Oct 03 '14 at 05:30
  • That's not an option. – Michael Burr Oct 03 '14 at 05:34