0

I'm trying to create an array of a struct, which I have done and I have to receive an input from the user. The first piece of data would be the description (a string). I have to allocate memory for it as well. I'm not how big the string is going to be to I want to check as it's going in, but I don't think I've set it up right. Can anyone give me a hint or a page I can look at to figure it out?

Greatly appreciated. Here are the important snipits of code:

struct myExpenses
{
    char *description;
    float cost;
};


int main (void)
{


struct myExpenses *pData = NULL;
struct myExpenses expenses[60];
int exit=0;
int i = 0;
char buffer[81] = "";


printf("Please enter all your descriptions:\n");
for (i=0;i < 60; i++)
{
    fgets(buffer,stdin);
    expenses[i].description=(char *)malloc sizeof(buffer);

} 
Robolisk
  • 1,682
  • 5
  • 22
  • 49
  • 2
    You've tagged this as `C++` but it looks like plain `C` code ? – Paul R Jan 13 '12 at 07:45
  • 1
    Since this is specifically C++, and not C, is there a reason why you're using `char[]`s as opposed to `std::string`s? – AusCBloke Jan 13 '12 at 07:46
  • Sorry, it's a C++ course, so I was sorta on autopilot. @AusCbloke: I don't understand what you're referring to. – Robolisk Jan 13 '12 at 07:49
  • 1
    Dont typecast the return value of `malloc` & AFAIK [`fgets`](http://pubs.opengroup.org/onlinepubs/007904875/functions/fgets.html) take 3 arguments – another.anon.coward Jan 13 '12 at 07:55
  • 1
    That `fgets` call is going to blow up in your face. Where's the maxlen parameter? – paxdiablo Jan 13 '12 at 07:56
  • Sorry what? If you mean if a bad input is to be inserted? Because that's something I'm not to worry about as all input is to be perfect, so for this I don't need checking. That's if this is what you're referring to. – Robolisk Jan 13 '12 at 08:09

2 Answers2

3

Instead of using malloc() you could use strdup that would automatically allocate the right sized buffer for you.

expenses[i].description = strdup( buffer );
Paul Mitchell
  • 3,241
  • 1
  • 19
  • 22
  • wow. Thanks, that works! But what would it look like if I chose to use malloc? – Robolisk Jan 13 '12 at 07:51
  • That would be: expenses[i].description = (char*) malloc( strlen( buffer ) + 1 ); strcpy( expenses[i].description, buffer ); – Paul Mitchell Jan 13 '12 at 07:53
  • There is no strdup in standard C - you may have to write your own: http://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c/252802#252802 – paxdiablo Jan 13 '12 at 07:55
  • @PaulMitchell: It is preferable not to typecast return value of `malloc` in C & also it does not *assure* you of memory being initalized to `0`, so maybe `calloc`? – another.anon.coward Jan 13 '12 at 07:59
  • Thanks another.anon.coward. OP asked how it would be done with malloc. Incidentally, why would you want the memory initialised to zeros? – Paul Mitchell Jan 13 '12 at 08:02
  • @PaulMitchell: Well you have to assure `NUL` termination thats why I said that! You have correctly allocated `strlen +1` space, but what about `NUL` termination is what I was wondering – another.anon.coward Jan 13 '12 at 08:06
  • What if the memory wasn't allocated correctly, wouldn't I need checking for NULL? – Robolisk Jan 13 '12 at 08:07
  • @another.anon.coward. Good idea, belt and braces. I like your thinking. I was just planning to depend on the null character that strcpy would put there. But better to make sure the entire buffer is filled with zeros first I suppose. – Paul Mitchell Jan 13 '12 at 08:10
  • @Robsta, yes you're correct. After the malloc() you should only contonue to copy the string into the newly allocated memory if the returned pointer is not NULL. – Paul Mitchell Jan 13 '12 at 08:16
2

Besides you missing a pair of parentheses around the malloc call and not really telling what the problem is, you just allocate the memory but do not copy the string. It can be done in one function call instead with the strdup function:

printf("Please enter all your descriptions:\n");
for (i=0;i < 60; i++)
{
    fgets(buffer,stdin);
    expenses[i].description=strdup(buffer);
}

Remember to call free on all the descriptions when you are done with them, or you will have a memory leak.

Edit How to use free on the given example:

for (i = 0; i < 60; i++)
    free(expenses[i].description);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • How do I go about calling the free? I know it's the free() function (I believe) but I'm not sure how to use it. – Robolisk Jan 13 '12 at 07:57
  • @Robsta It's just to call `free` with a pointer allocated by `malloc`, `calloc` or functions that uses those allocation functions, like `strdup`: `free(pointer);`. See my updated answer. – Some programmer dude Jan 13 '12 at 08:00
  • Thank you so much as well, I appreciate the help and time. – Robolisk Jan 13 '12 at 08:07