Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Type-casting problems

Reply
Thread Tools

Type-casting problems

 
 
Ramon
Guest
Posts: n/a
 
      03-20-2008
I have a pointer (result) of type void, which is passed (via parameter)
to another function named preocessResult().

At processResult() a pointer of type int (res) is malloced and data is
stored in the allocated space. res is type-casted to void * and
returned as result.


Everything seems to be ok, but when I run valgrind it gives the
following warnings:

==3186== Invalid read of size 1
==3186== at 0x401EB8C: memcpy (mc_replace_strmem.c:406)
==3186== by 0x804844A: foo (test.c:43)
==3186== by 0x8048462: main (test.c:54)
==3186== Address 0x416408B is not stack'd, malloc'd or (recently) free'd
==3186==
==3186== Invalid read of size 1
==3186== at 0x401EB91: memcpy (mc_replace_strmem.c:406)
==3186== by 0x804844A: foo (test.c:43)
==3186== by 0x8048462: main (test.c:54)
==3186== Address 0x416408A is not stack'd, malloc'd or (recently) free'd
==3186==
==3186== Invalid read of size 1
==3186== at 0x401EB98: memcpy (mc_replace_strmem.c:406)
==3186== by 0x804844A: foo (test.c:43)
==3186== by 0x8048462: main (test.c:54)
==3186== Address 0x4164089 is not stack'd, malloc'd or (recently) free'd
==3186==
==3186== Invalid read of size 1
==3186== at 0x401EB9F: memcpy (mc_replace_strmem.c:406)
==3186== by 0x804844A: foo (test.c:43)
==3186== by 0x8048462: main (test.c:54)
==3186== Address 0x4164088 is not stack'd, malloc'd or (recently) free'd


Can any one figures out where is the mistake(s) please?
Here is my code:



void processResult(void **result)
{
int *res = (int *) malloc(sizeof(int));

*res = 505;
*result = res;
}



void foo()
{
void *result = NULL;
struct mytask mtask;


processResult(&result);

if (result == NULL)
bzero( &mtask, sizeof(struct mytask) );
else
mtask = *((struct mytask *) result);
}
 
Reply With Quote
 
 
 
 
santosh
Guest
Posts: n/a
 
      03-20-2008
Ramon wrote:

> I have a pointer (result) of type void, which is passed (via
> parameter) to another function named preocessResult().
>
> At processResult() a pointer of type int (res) is malloced and data is
> stored in the allocated space. res is type-casted to void * and
> returned as result.
>
>
> Everything seems to be ok, but when I run valgrind it gives the
> following warnings:
>
> ==3186== Invalid read of size 1
> ==3186== at 0x401EB8C: memcpy (mc_replace_strmem.c:406)
> ==3186== by 0x804844A: foo (test.c:43)
> ==3186== by 0x8048462: main (test.c:54)
> ==3186== Address 0x416408B is not stack'd, malloc'd or (recently)
> free'd ==3186==
> ==3186== Invalid read of size 1
> ==3186== at 0x401EB91: memcpy (mc_replace_strmem.c:406)
> ==3186== by 0x804844A: foo (test.c:43)
> ==3186== by 0x8048462: main (test.c:54)
> ==3186== Address 0x416408A is not stack'd, malloc'd or (recently)
> free'd ==3186==
> ==3186== Invalid read of size 1
> ==3186== at 0x401EB98: memcpy (mc_replace_strmem.c:406)
> ==3186== by 0x804844A: foo (test.c:43)
> ==3186== by 0x8048462: main (test.c:54)
> ==3186== Address 0x4164089 is not stack'd, malloc'd or (recently)
> free'd ==3186==
> ==3186== Invalid read of size 1
> ==3186== at 0x401EB9F: memcpy (mc_replace_strmem.c:406)
> ==3186== by 0x804844A: foo (test.c:43)
> ==3186== by 0x8048462: main (test.c:54)
> ==3186== Address 0x4164088 is not stack'd, malloc'd or (recently)
> free'd
>
>
> Can any one figures out where is the mistake(s) please?
> Here is my code:
>
>
>
> void processResult(void **result)
> {
> int *res = (int *) malloc(sizeof(int));
>
> *res = 505;
> *result = res;
> }


The problem is that void ** is not similar to void * in C. void * can
point to any data type but void ** can only point to void *. This
function is poorly designed. I suggest:

int *processResult(void) {
int *p = malloc(WHATEVER);
return !p ? NULL : p;
}

or

void processResult(int **p) {
*p = malloc(WHATEVER);
return;
}

> void foo()
> {
> void *result = NULL;
> struct mytask mtask;
>
>
> processResult(&result);


Again void ** is not a generic pointer type like void * or char *.

> if (result == NULL)
> bzero( &mtask, sizeof(struct mytask) );
> else
> mtask = *((struct mytask *) result);
> }


 
Reply With Quote
 
 
 
 
Richard Tobin
Guest
Posts: n/a
 
      03-20-2008
In article <frt70u$10g$(E-Mail Removed)>,
Ramon <(E-Mail Removed)> wrote:

>void processResult(void **result)
>{
> int *res = (int *) malloc(sizeof(int));
>
> *res = 505;
> *result = res;
>}
>
>
>
>void foo()
>{
> void *result = NULL;
> struct mytask mtask;
>
>
> processResult(&result);
>
> if (result == NULL)
> bzero( &mtask, sizeof(struct mytask) );
> else
> mtask = *((struct mytask *) result);
>}


You haven't shown us the definition of struct mytask. But you are
casting result, which is a pointer to space for a single int, to
a pointer to struct mytask, and then dereferencing it. So if struct
mytask is bigger than an int, you are accessing unallocated memory.

It's also not allowed to modify memory through an int * pointer
and then refer to it through some other type (except a character
pointer), so if the struct doesn't start with an int you have
another problem. (Can someone else confirm I have interpreted
the aliasing rules correctly here?)

-- Richard
--
:wq
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-20-2008
Ramon <(E-Mail Removed)> writes:

> santosh wrote:
>> Ramon wrote:
>>
>>> I have a pointer (result) of type void, which is passed (via
>>> parameter) to another function named preocessResult().
>>>
>>> At processResult() a pointer of type int (res) is malloced and data is
>>> stored in the allocated space. res is type-casted to void * and
>>> returned as result.
>>>
>>> Everything seems to be ok, but when I run valgrind it gives the
>>> following warnings:
>>>
>>> ==3186== Invalid read of size 1
>>> ==3186== at 0x401EB8C: memcpy (mc_replace_strmem.c:406)
>>> ==3186== by 0x804844A: foo (test.c:43)
>>> ==3186== by 0x8048462: main (test.c:54)
>>> ==3186== Address 0x416408B is not stack'd, malloc'd or (recently)
>>> free'd ==3186==

<big snip>
>>> Can any one figures out where is the mistake(s) please?


Post, if you can, minimal code that exhibits the problem. I don't get
any error from valgrind if I add the minimum required to make your
code fragment work. The error (about memcpy) also suggests it relates
some other part of the code that you did not post

In addition, remove all but the required casts (two out of the three).
A cast will indicate dangerous or possibly non-portable code so it is
best not to have too many of them all over the place. Use them to
alert the reader to problems.

--
Ben.
 
Reply With Quote
 
Ramon
Guest
Posts: n/a
 
      03-20-2008
Richard Tobin wrote:
> In article <frt70u$10g$(E-Mail Removed)>,
> Ramon <(E-Mail Removed)> wrote:
>
>> void processResult(void **result)
>> {
>> int *res = (int *) malloc(sizeof(int));
>>
>> *res = 505;
>> *result = res;
>> }
>>
>>
>>
>> void foo()
>> {
>> void *result = NULL;
>> struct mytask mtask;
>>
>>
>> processResult(&result);
>>
>> if (result == NULL)
>> bzero( &mtask, sizeof(struct mytask) );
>> else
>> mtask = *((struct mytask *) result);
>> }

>
> You haven't shown us the definition of struct mytask. But you are
> casting result, which is a pointer to space for a single int, to
> a pointer to struct mytask, and then dereferencing it. So if struct
> mytask is bigger than an int, you are accessing unallocated memory.
>
> It's also not allowed to modify memory through an int * pointer
> and then refer to it through some other type (except a character
> pointer), so if the struct doesn't start with an int you have
> another problem. (Can someone else confirm I have interpreted
> the aliasing rules correctly here?)
>
> -- Richard



Excuse me... I've forgot to show you the definition of struct mytask, so
here it is:

struct mytask {
char info[100];
};

How can i solve this problem without changing the type of result -- i.e.
leaving result as a pointer to void?

Thanks
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      03-20-2008
In article <frtg1p$hdl$(E-Mail Removed)>,
Ramon <(E-Mail Removed)> wrote:
>>> int *res = (int *) malloc(sizeof(int));

....

>Excuse me... I've forgot to show you the definition of struct mytask, so
>here it is:
>
>struct mytask {
> char info[100];
>};
>
>How can i solve this problem without changing the type of result -- i.e.
>leaving result as a pointer to void?


What are you trying to achieve? Why do you think you can assign
a block of sizeof(int) bytes to something which is supposed to point
to 100 bytes?

-- Richard
--
:wq
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      03-20-2008
In article <(E-Mail Removed)>,
Ben Bacarisse <(E-Mail Removed)> wrote:

>Post, if you can, minimal code that exhibits the problem. I don't get
>any error from valgrind if I add the minimum required to make your
>code fragment work. The error (about memcpy) also suggests it relates
>some other part of the code that you did not post


The memcpy() is probably the structure assignment. And you probably
didn't see an error because in your minimum program the assigned-to
structure wasn't used, so the assignment was optimised away.

The error is simple: he allocates space for an int, then copies it as
a whole struct.

-- Richard
--
:wq
 
Reply With Quote
 
Ramon
Guest
Posts: n/a
 
      03-20-2008
Richard Tobin wrote:
> In article <frtg1p$hdl$(E-Mail Removed)>,
> Ramon <(E-Mail Removed)> wrote:
>>>> int *res = (int *) malloc(sizeof(int));

> ...
>
>> Excuse me... I've forgot to show you the definition of struct mytask, so
>> here it is:
>>
>> struct mytask {
>> char info[100];
>> };
>>
>> How can i solve this problem without changing the type of result -- i.e.
>> leaving result as a pointer to void?

>
> What are you trying to achieve? Why do you think you can assign
> a block of sizeof(int) bytes to something which is supposed to point
> to 100 bytes?
>
> -- Richard


As i've said before,
The problem is that processResult() is designed to be a generic
function; i.e. you don't know the type of result that it will process --
for example, sometimes it may return an integer, while sometimes it
may return a "string". It depends on the implementation of the user.

In this case it was an int, but it may be any other data-structure
(hopefully).
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      03-20-2008
In article <frtj7i$s9$(E-Mail Removed)>,
Ramon <(E-Mail Removed)> wrote:

>> What are you trying to achieve? Why do you think you can assign
>> a block of sizeof(int) bytes to something which is supposed to point
>> to 100 bytes?


>As i've said before,
>The problem is that processResult() is designed to be a generic
>function; i.e. you don't know the type of result that it will process --
> for example, sometimes it may return an integer, while sometimes it
>may return a "string". It depends on the implementation of the user.
>
>In this case it was an int, but it may be any other data-structure
>(hopefully).


If it was an int, why did you assign it to a struct?

-- Richard


--
:wq
 
Reply With Quote
 
Ramon
Guest
Posts: n/a
 
      03-20-2008
Richard Tobin wrote:
> In article <frtj7i$s9$(E-Mail Removed)>,
> Ramon <(E-Mail Removed)> wrote:
>
>>> What are you trying to achieve? Why do you think you can assign
>>> a block of sizeof(int) bytes to something which is supposed to point
>>> to 100 bytes?

>
>> As i've said before,
>> The problem is that processResult() is designed to be a generic
>> function; i.e. you don't know the type of result that it will process --
>> for example, sometimes it may return an integer, while sometimes it
>> may return a "string". It depends on the implementation of the user.
>>
>> In this case it was an int, but it may be any other data-structure
>> (hopefully).

>
> If it was an int, why did you assign it to a struct?
>
> -- Richard
>
>



Ok here is non-C stuff. As far as i know, POSIX message queues do not
allows you to transmit pointers from one process to another (since each
process has a protected address space). Hence one cannot assign an int
to a void and post it to a message queue.

To what type (except void) can i cast it (the int or something)?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Saving the web, charset problems and symbols problems Sak Na rede Ruby 0 01-30-2009 05:05 AM
Problems, problems for newbie Shelly ASP .Net 1 09-03-2007 02:10 AM
Problems compiling simple C++ code (also problems with std::string) Susan Baker C++ 2 06-26-2005 01:43 AM
Re: sound problems and modem problems Harold Potter Computer Support 5 12-04-2003 04:12 PM



Advertisments