Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

TheToiletDuck

casting

This topic is 6513 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am having a problem with void pointers. I''m using straight C, not C++. So, I''ve got my void pointer, and I''ve malloc''d enough memory to hold a float: void *ptr; ptr = malloc(sizeof(float)); now, I want to assign a floating point value to this ptr = 17.65f; This won''t work. *ptr = 17.65f; Neither will this. *(float *)ptr = 17.65f; This seems to be the solution, although I can''t understand why, when this is legal, assuming a couple of other declarations and a good call to fopen(). int myints[10]; fread(myints, sizeof(int)*10, 1, somefile); Now, why no casting with fread()? Is there any other strange legailties with casting like this? such as: float *flptr; flptr = (float *)malloc(sizeof(float)); fread(flptr, sizeof(float), 1, somefile); Do I need a cast then? Learning all these cases is driving me round the bend, can someone shed some light on it, or point me in the direction of a good link? Any help appreciated.

Share this post


Link to post
Share on other sites
Advertisement

I''m only a beginner, but I think it''s to do with whether the compiler knows the size of the data pointed too.

i.e, if you do this...

LPVOID lpVoid = malloc(sizeof(float)*10);

... then when you assign a float to some of this data, the compiler doesn''t know the size of the array elements.

Alternatively, if you create a temorary pointer to a float, it can be filled in and then cast to lpvoid.

i.e.

float* lpFloat = (float*) malloc(sizeof(float*10));
*lpFloat = 3.142f;
LPVOID lpVoid = (LPVOID) lpFloat;

I hope I was of some help...

Jon.

Share this post


Link to post
Share on other sites
Here is how I would do it if I had to and according to the books I read, it''s supposed to work. I''ll explain after...

(float)(*ptr) = 17.65f;

The reasons for this is because you actually want to typecat the pointer and not just the variable ptr. As I said, this is what was in my books. Didn''t test it myself but as far as I can tell, it looks logical. It works the same way as typecasting a pointer to function... Hope this works...





Cyberdrek
Headhunter Soft
DLC Multimedia

Share this post


Link to post
Share on other sites
Actually, I''m pretty sure that "(float)(*ptr) = 17.65f;" won''t work. I see two problems.

First, if ptr is of type (void*) then there is no way to deref it, since the compiler doesn''t know how big the data pointed to is (as j0n3z mentioned).

Second, even if you change ptr to a know type such as (char*), the left side of the equation doesn''t evaluate to an l-value. By this I mean that "(float)(*ptr)" doesn''t evaluate to a valid variable. The compiler is trying to deref ptr to get a char value (into a register or whatever) and then convert that value into a float. So far no problem. Then it wants to store into that value, but it''s not a variable, it''s just a value in a register.

On the other hand, when you do "*(float*)ptr", then your telling the compiler to take the address in the variable ptr, assume that it points to a float, and then use the float that it points to. Since this evaluates to an object (a spot in memory) instead of just a casted value, it''ll work just fine.

Hope this helps.
...Syzygy

Share this post


Link to post
Share on other sites
I think what you really need to do is develop an understanding for what type-casting really does, and then you''ll be able to work out any problems you have yourself.

In your first example you have:

void *ptr;

ptr = malloc(sizeof(float));

Which gives you a pointer that references a space large enough to hold a float. However, you could still store an int or whatnot with that pointer, so you have to explicitly tell the compiler what you''re doing. ptr = 17.65f won''t work because you''re trying to assign to the pointer and not the memory it references. *ptr = 17.65f would work if ptr was declared as float *ptr, but it wasn''t. Therefore you need your typecasting. Breaking it down a bit, you first cast using (float *)ptr to make it a pointer to a float instead of void. Then you simply dereference it like normal with *.

I''m not sure where you think you should need typecasting in the second example, ao I''ll skip that.

In your last example, the (float *) typecast in the second line isn''t really necessary. malloc() returns a void pointer which can be safely typecast implicitly to the type of the l-value. No typecasting is necessary in the last line either, as the pointer is cast to void and no type information is passed to fread() anyway.

Hope that''s helpful, though I''m afraid I may not have made much sense.

Share this post


Link to post
Share on other sites
quote:
Original post by TheToiletDuck
So, I''ve got my void pointer, and I''ve malloc''d enough memory to hold a float:

void *ptr;
ptr = malloc(sizeof(float));

ptr = 17.65f;
This won''t work.



Correct, it shouldn''t work. ptr is a pointer (ie, a memory address) and you''re trying to give it a floating-point value? The compiler correctly flags this as an error.

quote:

*ptr = 17.65f;
Neither will this.



Again, this shouldn''t work. ptr is a pointer, but it is a pointer to void and trying to dereference (*) it makes no sense. You allocated enough memory to hold a float, but not an actual float.

quote:

*(float *)ptr = 17.65f;
This seems to be the solution, although I can''t understand why, when this is legal, assuming a couple of other declarations and a good call to fopen().

int myints[10];
fread(myints, sizeof(int)*10, 1, somefile);
Now, why no casting with fread()?




Yes, if you require that ptr be a pointer to void, then this is the correct solution. You first force the compiler to recognize it as pointer to float with the (float*) typecast, and THEN you dereference it. Since the compiler temporarily recognizes the void pointer as a float pointer, dereferencing gives you a float.

In the second part, the first parameter of fread is a void* . While you have not put in a typecast, the compiler has. It is allowed to automatically cast to void*, but not always from void*. (Actually, in C++, I think the compiler is never allowed to cast from void*.)

quote:

Is there any other strange legailties with casting like this?
such as:

float *flptr;
flptr = (float *)malloc(sizeof(float));
fread(flptr, sizeof(float), 1, somefile);

Do I need a cast then?



Not in the fread call. The compiler will automatically typecast flptr to void* in the call to fread. Same as above.


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!