10

I was struggling to fix a code today, then I come across something similar to:

typedef struct {
int a; 
int b; 
int c;
int d;
char* word;
} mystruct;

int main(int argc, char **argv){

    mystruct* structptr = malloc(sizeof(mystruct));
    if (structptr==NULL) {
        printf("ERROR!")
        ...
    }
    ...
    free(structptr);

    return 0;
}

the code was giving lots of memory errors due to the fact, that char* word is a string of variable length, and malloc was not allocating enough memory for it. In fact it was only allocating 20 Bytes for the whole struct. Is there a way around this issue, without turning the char* into sth like char word[50]?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
H_squared
  • 1,251
  • 2
  • 15
  • 32
  • saw that you had a comment, but then removed it. Please edit your question with more info or submit a second question. There are methods to cope with a `char` vector that changes in length. – JackCColeman Aug 15 '13 at 07:46
  • I added the comment then found the answer in the comments below. I believe, a fixed buffer size is actually the best solution since word will represent a name and names shouldn't be as long as a novel ;) . Thanks for the help. I was just really curious about allocating memory for variable strings, that's why I asked. But I was going to switch to fixed length arrays anyway. – H_squared Aug 15 '13 at 07:53
  • these days space (i.e. RAM) is plentiful, so in most cases defining an array of chars as large as 1024 won't cause a problem. I/O buffers are routinely much larger than this. – JackCColeman Aug 15 '13 at 08:01
  • 1
    @hhachem You clearly don't understand pointers very well. Please read about pointers and arrays (for example, [here](http://c-faq.com/aryptr/index.html)) –  Aug 15 '13 at 08:05
  • Possible duplicate of [Allocation of memory for char array](http://stackoverflow.com/questions/9081204/allocation-of-memory-for-char-array) – GSerg Apr 30 '16 at 20:04

6 Answers6

22

You are allocating only memory for the structure itself. This includes the pointer to char, which is only 4 bytes on 32bit system, because it is part of the structure. It does NOT include memory for an unknown length of string, so if you want to have a string, you must manually allocate memory for that as well. If you are just copying a string, you can use strdup() which allocates and copies the string. You must still free the memory yourself though.

 mystruct* structptr = malloc(sizeof(mystruct));
 structptr->word = malloc(mystringlength+1);

 ....

 free(structptr->word);
 free(structptr);

If you don't want to allocate memory for the string yourself, your only choice is to declare a fixed length array in your struct. Then it will be part of the structure, and sizeof(mystruct) will include it. If this is applicable or not, depends on your design though.

Devolus
  • 21,661
  • 13
  • 66
  • 113
  • 1
    @H2CO3, I don't think Devolus appreciates your perspective. – JackCColeman Aug 15 '13 at 07:33
  • 1
    @JackCColeman, especially since it is not very constructive to critzize wihtout any information what would be wrong. – Devolus Aug 15 '13 at 07:35
  • @Devolus, to give H2CO3 credit, I think he was actually talking to hhachem or was being as sarcastic as myself! – JackCColeman Aug 15 '13 at 07:38
  • @JackCColeman, oh! I thought he was adressing me, as it was a comment to my post. :o – Devolus Aug 15 '13 at 07:39
  • The opposite is true. If the length is not known, you must dynamically allocate the memory, unless you can put an upper limit on your stringlength. Of course, you should also add code, to make sure that the fixed length is not exceeded in this cases (and don't forget to consider `0` byte) when you deal with strings. So if you say that no string can be longer then i.e. 50+1, an array is easier to maintain. – Devolus Aug 15 '13 at 07:43
  • @Devolus damn, I wanted to leave this comment on the question, not on the answer! Sorry, I misplaced it. –  Aug 15 '13 at 08:03
  • @H2CO3, No problem, I was only confused at first. :) – Devolus Aug 15 '13 at 08:05
3

Add a second malloc for whatever length (N) you need for word

   mystruct* structptr = malloc(sizeof(mystruct));

   structptr->word = malloc(sizeof(char) * N);
JackCColeman
  • 3,777
  • 1
  • 15
  • 21
3

as you can read here you need to allocate the char * separately :

mystruct* structptr = malloc(sizeof(mystruct));
structptr->word = malloc(sizeof(WhatSizeYouWant));
No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
1

When you allocate memory for structptr, the pointer word in the struct has no valid memory to point. So you either malloc a piece of memory for word, too, or make word point to another character.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
0

malloc the outer struct will only allocate 1 byte memory pointed by *word since it is a 'char *' type. If you want to allocate more than 1 byte of memory pointed by word, there are 2 options:

  1. Like what you said, declare it as char word[50] instead of `char *'
  2. malloc/calloc (I personally prefer calloc, saving you the trouble of zeromemory, which is a very important..) the outer struct, then malloc/calloc the inner word as well. Remember to call free twice as well in this case.
Angela Yan
  • 205
  • 4
  • 14
-2

Use word=malloc(128);

this will allocate 128 bytes to your varible word,

Abhishek
  • 874
  • 2
  • 8
  • 23