sam32
sam32

Reputation: 335

realloc int pointer present in a structure [C]

I want to malloc an integer pointer present inside a structure.

If in future I need to expand the array, I use realloc.

something like this:

typedef struct {
   int *temp,count
}foo;

main()
{
    foo *fake = (foo*)malloc(1*sizeof(foo));
    fake.count = 0;

    ++(fake.count);
    fake.temp = (int*)malloc((fake.count)*sizeof(int));

    /* I do something */

    /*now i want to realloc "temp" to ++(fake.count) */

Is this way of doing that correct?

    ++(fake.count);
    fake.temp = (int*)realloc(fake.temp,(fake.count)*sizeof(int));

Upvotes: 1

Views: 1653

Answers (3)

Aftnix
Aftnix

Reputation: 4589

Its difficult to say if it will be OK to do realloc that way without knowing what is I do something. But you can start with this....

#include <stdio.h>
#include <stdlib.h>

typedef struct {
 int *temp,count;
 }foo;

extern char etext, edata, end;
int main()
{
   printf("Heap before first malloc %p\n", sbrk(0));

   foo *fake = malloc(1*sizeof(foo));

   printf("heap after first malloc %p\n", sbrk(0));

   fake->count = 0;
   ++(fake->count);
   fake->temp = malloc((fake->count)*sizeof(int));
   printf("heap after second malloc %p\n", sbrk(0));

   fake->count += 2;
   fake->temp = realloc(fake->temp, (fake->count) * sizeof(int));
   printf("count %d\n", fake->count);

   printf("heap after realloc %p\n", sbrk(0));
   printf("program text segment(etext)      %10p\n", &etext);
   printf("initialized data segment(edata)  %10p\n", &edata);
   printf("uninitialized data segment (end) %10p\n", &end);

   return 0;
}

This will output your heap addresses also.

Heap before first malloc 0x239b000
heap after first malloc 0x23bc000
heap after second malloc 0x23bc000
count 3
heap after realloc 0x23bc000
program text segment(etext)        0x400816
initialized data segment(edata)    0x600bc4
uninitialized data segment (end)   0x600bd8
  1. You don't need a cast for malloc().

  2. Considering calloc() to clear out your memory. As you are reallocating, you can get wrongly initialized memory block. (like recently free'd blocks).

  3. Always check the return value of realloc() before using it. chance of failed realloc() is pretty high then malloc().

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477110

In principle, yes.

However, you should make sure that your code survives possible errors in realloc, like so:

int * p = realloc(fake->temp, (fake->count + 1) * sizeof(int));
if (p) { fake->temp = p; ++fake->count; }
else   { /* error! But fake was untouched. */ }

Also, you should say int main(void) for your main function declaration. Finally, you shouldn't cast the result of malloc or realloc, since a void* is implicitly convertible to any other object pointer.

One more: Your coding style is really difficult for others to read. I'd write the struct definition like this:

typedef struct foo_
{
    int * temp;
    int   count;
} foo;

And even one more: Do you need to allocate fake dynamically? If not, an automatic variable foo fake; may be easier to maintain. In any event, if you do want to allocate it dynamically, don't cast and don't repeat the type, like so:

foo * fake = malloc(sizeof *fake);
// or:       calloc(1, sizeof *fake);      // this will zero out the memory

Upvotes: 2

Carl Norum
Carl Norum

Reputation: 224962

  1. You don't need to cast the return value from malloc or realloc in a C program.
  2. Don't directly assign the result of your realloc call to the same variable. If it fails, you'll leak the original allocation. Do something like this instead:

    void *err = realloc(pointer, newSize);
    if (err != NULL)
    {
        pointer = err;
    }
    
  3. Nitpick - multiplying by 1 looks weird.

Upvotes: 2

Related Questions