0

I am allocating pointer to head structure using malloc, but I would like to have 'title' field have size of 100 char elements. How to properly do it?

struct tail{
    int x;
};

struct head{
    char *title;
    struct tail *next;
};

void function(){
    struct head *h;
    //this (program won't know how much to allocate for 'title':
    h = (struct head*)malloc(sizeof(struct head));

    //VS this (Segmentation fault (core dumped)):
    h->title = (char*)malloc(sizeof(char)*255);
    h->next = (struct tail*)malloc(sizeof(struct tail*));

    /*
    or maybe I should alloc h, then realloc title?
    If that's the answer, how will I free whole structure later?
    */
}

ps. I am not using char title[100] on purpose.

edit note. (char) was a typo, I have (char*) in my code

John Doe
  • 135
  • 1
  • 13
  • Would you mind explaining your purpose of not using `char title[100]`? – hetepeperfan Dec 09 '13 at 21:58
  • @hetepeperfan Mainly learning purposes. I know how to allocate this structure when using char title[100]. PS. Also this way I could set title's size to any needed size. (not always 100) – John Doe Dec 09 '13 at 22:01
  • Since you are learning, it will be wise for you **not** to cast the result of `malloc`. One of your casts is actually wrong, while the other two are redundant and can actually mask real errors. – dreamlax Dec 09 '13 at 22:12
  • you don't have to cast the `void*` that `malloc` returns in c, in c++ one should do this, however, than one would use `new`. – hetepeperfan Dec 09 '13 at 22:17

3 Answers3

2

Are you compiling with -wall?

If you look at this warning you should get

so.c:16:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

The return value of malloc is a void pointer, which points to the piece of memory you are allocating - you are casting the address of the memory to a char, which is because you have missing out the pointer declaration * and thereby truncating the actual address, which then results in your segfault.

C does know how much memory to allocate for the struct from the start, as pointers have a fixed size, which is all that is being allocated when you do a malloc on your head/tail structure.

Jesper Bangsholt
  • 544
  • 4
  • 11
0

Why not use the first way, and then allocate space for title?

h = malloc(sizeof(struct head));
h -> title = malloc(sizeof(char) * 100);
h -> next = malloc(sizeof(struct tail*));

The trick was to remember that title is a char * so all you need in h is space for a pointer, not the actual array.

You can free this simply by using:

free(h -> title);
free(h -> next);
free(h);

The problem with your second method is that h wasn't allocated, so it segfaulted. Also, you were casting the result of malloc (a void *) to a char, which doesn't really make sense - I think you meant to cast to a char *, which isn't needed anyway, because C can convert from void * automatically.

AAA
  • 1,364
  • 1
  • 10
  • 15
  • You should not cast the result of `malloc` at all. There is no need, since C allows implicit conversion from pointer to void to pointer to object types. – dreamlax Dec 09 '13 at 22:20
0

you could do someting like create a function that creates a struct head with a given title size. Remember that you must (should) also create a free_head function that is able to destroy an object created by the create_head fucntion below.

struct head* create_head( unsigned title_size) {
     struct tail* t = malloc (sizof(struct tail) );
     if ( ! tail ){
         return NULL;
     }
     char* title = malloc ( title_size * sizeof(char) );
     if ( !title ){
          free(t)
          return NULL;
     }
     struct head* h = malloc (sizeof (struct head) );
     if ( !head ){
         free (t);
         free (title);
         return NULL;
     }
     head->title = title;
     head->next = t;
     return head;
}

Now you could simply use use the function like:

struct head* = create_head(100);

And then of course you need to write a some code the destroys the struct head properly otherwise you create a memory leak. Also rember that this function does not allocate one extra char for a terminating '\0' byte. to terminate a C string

succes!

hetepeperfan
  • 4,292
  • 1
  • 29
  • 47