0

What does this statement mean?

//allocated memory for Device info

(*PppsCoreStructure)->psDeviceDetails=(sDeviceDetails **)calloc(CORE_DEVICEINFO_SIZE, sizeof(sDeviceDetails*));

I know that '(*PppsCoreStructure)->psDeviceDetails' is a pointer to pointer. But I am not being able to imagine how calloc can return pointer to pointer? I'm a beginner please help

SHRI
  • 2,406
  • 6
  • 32
  • 48

3 Answers3

3

This call to calloc allocates sufficient space for CORE_DEVICEINFO_SIZE pointers to sDeviceDetails objects. calloc returns a simple memory buffer that can be used to store anything; in this case, pointers.

(Note that relying on calloc to return buffers filled with null pointers is not portable: it returns zero-filled buffers, but the null pointer is not necessarily all zeroes. It is on common platforms, though.)

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Thanks for your reply Sir, but I want know how (sDeviceDetails *)calloc is different from (sDeviceDetails **)calloc. – SHRI Nov 15 '11 at 12:51
  • @SHRI: as I explained, `calloc` is used here to allocate space for pointers to `sDeviceDetails`. You'd use a cast `sDeviceDetails*` when allocating space for a `struct sDeviceDetails`, or an array of those. – Fred Foo Nov 15 '11 at 12:55
  • `(sDeviceDetails *)calloc(...)` requires that `sDeviceDetails` is an array or pointer type (or that you only asked to `calloc` a single element -- i.e. CORE_DEVICEINFO_SIZE = 1). Because `calloc` allocates several sequential chunks of memory, its return values are pointers to pointers the same way that pointers-to-arrays are like pointers-to-pointers – tobyodavies Nov 15 '11 at 12:58
3

The function allocates an array of pointers. CORE_DEVICEINFO_SIZE is the number of pointers in this array.

(sDeviceDetails **) means that the programmer who wrote the code doesn't know how void-pointer casts work in the C language. The cast is redundant and should be removed.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Sorry, why is it redundant to stop compiler warnings? It makes the real warnings possible to see no? – tobyodavies Nov 15 '11 at 13:00
  • 2
    This typecast _removes_ the real warnings, for example if you accidently try to store a pointer-to-pointer inside a pointer. That's why this is bad practice. (C++ is another matter, but this question is about C.) [Read any number of posts about it on SO](http://stackoverflow.com/questions/4993327/is-typecast-required-in-malloc) – Lundin Nov 15 '11 at 13:06
1
  • (*PppsCoreStructure)->psDeviceDetails is declared with type sDeviceDetails **
  • The return value of calloc() is of type void*
  • (sDeviceDetails **)calloc(...) casts the return value of calloc to be of type sDeviceDetails **

In the C++ language this type cast is essential, although in C++ one would normally not be using calloc and would probably be using C++ casts.

In the C language the type cast is not needed because a void* pointer is assignment compatible with all other pointer types.


In a comment you state

But I want know how sDeviceDetails* is different from sDeviceDetails**

and I suspect that this is in fact your real question.

The answer is simple enough: T* is a pointer-to-T and T** is a pointer-to-pointer-to-T.

Paul R
  • 208,748
  • 37
  • 389
  • 560
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I mean as I know, calloc/malloc creates a new space and reurns its address to a pointer. So T* is correct. I understood. But for T**, calloc/malloc should create new space, assign it to a pointer. And again, that pointer's address will be assigned to T**. What I thought is correct? If correct, what about that middle pointer? – SHRI Nov 15 '11 at 13:11
  • 1
    @SHRI Your call to `calloc` only allocates the array of pointers. You must then allocate each pointer in that array. – David Heffernan Nov 15 '11 at 13:16