0

For my C application I tried to initialize memory. I am aware of the slower calloc, but fortunatelly there is no need to track performance.

I need memory space for just one unsigned int element (up to 65535).

This is the part of my code that doesn't work:

//Declaration
unsigned int part1;

//Allocation
part1 = (unsigned int) calloc (1,sizeof(unsigned int));

That throws the compiler warning:

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

Why does the above code doesn't work, where...

unsigned long size;
size =(unsigned long) calloc (1,sizeof(unsigned long));

...works great?

Thank you!

user1252280
  • 373
  • 1
  • 7
  • 23

3 Answers3

4

calloc returns void* so you should use it like

unsigned int* part1 = calloc (1,sizeof(*part1));

then assign it like

*part1 = 42;

If you have allocated space for several elements

part1[0] = 42; // valid indices are [0..nmemb-1]

may be clearer.

Note that you also have to free this memory later

free(part1);

Alternatively, if you only need a single element, just declare it on the stack

unsigned int part1 = 42;

Regarding why casting a point to unsigned long doesn't generate a warning, sizeof(void*)==sizeof(unsigned long) on your platform. Your code would not be portable if you relied on this. More importantly, if you use a pointer to store a single integer, you'd leak your newly allocated memory and be unable to ever store more than one element of an array.

simonc
  • 41,632
  • 12
  • 85
  • 103
  • Don't we need to typecast? – Hariprasad Dec 23 '13 at 08:54
  • 2
    @Hariprasad No, In C we don't need. Read [Do I cast the result of malloc?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858) – Grijesh Chauhan Dec 23 '13 at 08:55
  • Marked as right answer. I knew the return of void* because I read it up...but I am quite new to C and the whole memory management is kinda hard to understand. Besides that: Great answer and understandable explanation of my question regarding the unsigned long confusion. thanks! – user1252280 Dec 23 '13 at 09:11
0

Use code below. Calloc() will return void* So you will have to convert it in the SomeType*

unsigned int* part1;

//Allocation
part1 = (unsigned int*) calloc (1,sizeof(unsigned int));
Digital_Reality
  • 4,488
  • 1
  • 29
  • 31
  • 2
    Conversion from `void*` to `unsigned int*` will be implicit. You don't need the cast in C. See Grijesh's comment on my answer for details. – simonc Dec 23 '13 at 08:59
  • Oh yes! Right.. But OP still have to declare that as pointer to int (whatever type he needs) – Digital_Reality Dec 23 '13 at 09:01
  • c does the implicit conversion of void* to any other pointer type. You should not typecast it explicitly. – Abhineet Dec 23 '13 at 09:03
0

you have to understand these types of memory allocation to avoid doing these errors :

Static memory allocation:

unsigned int part1;

The size is fixed. It needs to be known at compile time. Freeing the memory is done on scope exit directly. The variable is allocated on the stack. indeed, this type of memory allocation is done at compile time, its lifetime is entire runtime of program. the advantage of using this type of allocation is efficient execution time. but if we declare more static data space than we need we waste space, this is the disadvantage of this type.

Dynamic memory allocation:

unsigned int* part1 = calloc( n, sizeof(unsigned int) );

The size can vary, you can find the value at runtime. You are responsible for freeing the memory with free() predefined C function. The variable is allocated on the heap.

you can see more details in web site : http://www.cs.virginia.edu/~son/cs414.f05/lec11.slides.pdf

Anis_Stack
  • 3,306
  • 4
  • 30
  • 53