linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Into the Void
@ 2005-01-26 13:45 Jeff.Fellin
  2005-01-26 16:11 ` Scott
  0 siblings, 1 reply; 12+ messages in thread
From: Jeff.Fellin @ 2005-01-26 13:45 UTC (permalink / raw)
  To: drmemory; +Cc: linux-c-programming, linux-c-programming-owner


The reason you are getting the references to void is the function prototype
for memcpy is:

      memcpy (void *dest, void *src, size_t n);

You are passing char* pointers which are not void * pointers. You have to
correct your arguments
to remove the error messages. Please use man memcpy() for more details.


Jeff Fellin
RFL Electronics
Jeff.Fellin@rflelect.com
973 334-3100, x 327


^ permalink raw reply	[flat|nested] 12+ messages in thread
* RE: Into the Void
@ 2005-02-02 18:17 Huber, George K RDECOM CERDEC STCD SRI
  0 siblings, 0 replies; 12+ messages in thread
From: Huber, George K RDECOM CERDEC STCD SRI @ 2005-02-02 18:17 UTC (permalink / raw)
  To: 'Glynn Clements', linux-c-programming



-----Original Message-----
From: Glynn Clements [mailto:glynn@gclements.plus.com]
Sent: Wednesday, February 02, 2005 7:16 AM
To: linux-c-programming@vger.kernel.org
Subject: RE: Into the Void

Glynn wrote:

>Huber, George K RDECOM CERDEC STCD SRI wrote:

>> Well we have not put anything in that memory location yet, and
>> as I recall, under Linux any memory is zero-out when returned by malloc to
>> help prevent information leakage from one application to another.

>Memory contains zeroes when it is first given to the process by the
>kernel. Whether or not memory returned from malloc() contains zeroes
>depends upon whether that memory has been used previously by the
>current process.

Agreed.

I was thinking of the case where there are multiple processes running at a time.  Each
process has it quanta `on the' processor and then another is swapped in.  I do not 
recall ever hearing if on a switch from one process to another if memory is reset or if 
the pages are just swapped back in.

Any one have information on this?

George

^ permalink raw reply	[flat|nested] 12+ messages in thread
* RE: Into the Void
@ 2005-02-01 15:32 Huber, George K RDECOM CERDEC STCD SRI
  2005-02-02 12:15 ` Glynn Clements
  0 siblings, 1 reply; 12+ messages in thread
From: Huber, George K RDECOM CERDEC STCD SRI @ 2005-02-01 15:32 UTC (permalink / raw)
  To: 'Amit Dang', linux-c-programming

Amit wrote:

>Hi George, I was just going through the code. In second code, line
>((char*)memcpy((void*)*in_buf, out_buf, 4))[4] = '\0';
>why does (void *)*in_buf returns NULL. I tried typecasting different type of
>pointers and its always NULL.

Because it is NULL :-).

Seriously, lets forget about type-casting for a moment and just concentrate 
on the first term as written:

         *in_buf

Now consider what this means.  In english, we would read this as "dereference 
in_buf", or in other words "get the value in the memory address that is 
contained in the variable in_buf".  But what memory address does in_buf
contain, and more importaintly what is stored at the memory address?

In the code, I wrote this:

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

#define BUF_LEN 6

int main()
{
    char*   in_buf = malloc(BUF_LEN*sizeof(char));
    char*   out_buf = malloc(BUF_LEN*sizeof(char));
    strcpy(out_buf, "Test");
    ((char*)memcpy((void*)*in_buf, out_buf, 4))[4] = '\0';
...
=======================================================================

So we see that in_buf contains the address of a memory location that will
hold a character, pictorially (excuse the ASCII art, and assuming that the 
size of a character is one byte).

       2004   2005   2006   2007   2008   2009    <---- hypothetical addresses
      +------+------+------+------+------+------+
      |  1   |      |      |      |      |      |
      | byte |      |      |      |      |      |
      +------+------+------+------+------+------+
      ^
      |
      |
      in_buf

So from the picture, in_buf would contain the value of `2004' and *in_buf 
would be asking for the value currently in memory location 2004.  But what 
is in there?  Well we have not put anything in that memory location yet, and
as I recall, under Linux any memory is zero-out when returned by malloc to
help prevent information leakage from one application to another.  So while
we have not put anything in that memory address, malloc has initialized it
to 0 for us.  Thus *in_buf will return zero (and since NULL is 0, we can 
also think of getting NULL).

Now with this, lets think about the original line of code:

   ((char*)memcpy((void*)*in_buf, out_buf, 4))[4] = '\0';

and lets think about what happens when this line is executed.  First *in_buf
is evaluated and returns NULL (or 0).  This is then type-cast into a void 
pointer (remembering that NULL is a valid pointer value so the type cast 
works just fine).  Finally the contents of memory starting at out_buf is 
attempeted to be copied to the memory location starting at 0 - thus the 
segmentation fault.

Finally, consider the warning that compiling the code gives:

warning: cast to pointer from integer of different size

Lets see if we can understand where this is coming from.  First, under IA-32 Linux
pointers are 32-bit unsigned integer values.  Now when we do a dereference on in_buf
we get back a single byte (assuming characters a single byte quantities) or an 8-bit
vaule.  So the expression `(void*)*in_buf' is attempting to take an 8-bit value and
make it a 32-bit pointer.  The converion 8-bit integer to 32-bit integer is allowed and 
will happen transparently (in most cases) because there is not loss of data.  However 
the compiler is warning us that in this case a pointer is involved which is 
probably not what we want. 

Hope this helps,
George

^ permalink raw reply	[flat|nested] 12+ messages in thread
* RE: Into the Void
@ 2005-01-27 17:58 Huber, George K RDECOM CERDEC STCD SRI
  2005-01-28  4:36 ` Amit Dang
  0 siblings, 1 reply; 12+ messages in thread
From: Huber, George K RDECOM CERDEC STCD SRI @ 2005-01-27 17:58 UTC (permalink / raw)
  To: 'Scott', 'linux-c-programming@vger.kernel.org'

Scott wrote:

>Thanks for your help; I actually managed to get the program to compile
>with no errors, but now am getting a segmentation fault which I can't
>track down, so I'll probably be back to plague you folks some more!

Even without seeing your code, I probably can guess what is happening.
Consider the following sample program (with no error checking)

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

#define BUF_LEN 6

int main()
{
    char*   in_buf = malloc(BUF_LEN*sizeof(char));
    char*   out_buf = malloc(BUF_LEN*sizeof(char));

    strcpy(out_buf, "Test");

    ((char*)memcpy((void*)in_buf, out_buf, 4))[4] = '\0';
  
    printf("%s\n", in_buf);
   
    return 0;
}
======================================================================

The above program compiles cleanly and produces the expected output.

However, if the above program is changed to this:

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

#define BUF_LEN 6

int main()
{
    char*   in_buf = malloc(BUF_LEN*sizeof(char));
    char*   out_buf = malloc(BUF_LEN*sizeof(char));

    strcpy(out_buf, "Test");

    ((char*)memcpy((void*)*in_buf, out_buf, 4))[4] = '\0';
  
    printf("%s\n", in_buf);
   
    return 0;
}
======================================================================

we get a single warning (warning: cast to pointer from integer of 
different size) and the program segfaults when it is run.  

Make sure you are not dereferencing the the first parametere to memcpy.

Also, if the above does not help, try compiling with debugging support 
turned on (i.e. gcc -g ...) and then run the program under gdb.  Using the 
gdb `where' command will show you what line you are seg-faulting on.

Finally, I find it useful to alway compile using the flags "-ansi -pedantic 
-Wall" (or "-std=c99 -pedantic -Wall) and treat any warning as errors.  I 
know it can be a pain-in-the-arse, but I find that it does minimize run-time
errors.

George

^ permalink raw reply	[flat|nested] 12+ messages in thread
* RE: Into the Void
@ 2005-01-26 16:02 Huber, George K RDECOM CERDEC STCD SRI
  0 siblings, 0 replies; 12+ messages in thread
From: Huber, George K RDECOM CERDEC STCD SRI @ 2005-01-26 16:02 UTC (permalink / raw)
  To: linux-c-programming

Scott wrote:

>Years ago, I learned this trick from somebody in the C/C++ Journal, or
>whatever that rag was called:
>
>           memcpy(*data_buf,bp,len)[len] = '\0';
>
>I get the following error:
>
>indatax.c: In function `read_datum':
>indatax.c:374: warning: dereferencing `void *' pointer
>indatax.c:374: invalid use of void expression

My first question would be what is the type of `data_buf'?

Secondly, as others have mentioned, the prototype for memcpy is:

void* memcpy(void* dest, const void* src, size_t len);

so you need to supply the address of a source buffer and the address
of a destination buffer.  The statement `*data_buf' can be thought of 
as saying "get the value stored in the memory location pointed to by
data_buf" (i.e. dereference data_buf).

From looking at your example, I take that what you are doing is copying 
data in `bp' to the buffer `data_buf' and then appending a null-terminator
to `data-buf'.  Assuming that data_buf and buf are properly declared and 
defined, the following should work:

       ((char*)memcpy((void*)data_buf, (const void*)bp, len))[len];

While your `trick' works, it probably is a maintenance nightmare - the 
intent is not immediately clear.  I would probably do the same thing in
two steps:

memset((void*)data_buf, '\0', len);                 // fills data_buf with nulls...
memcpy((void*)data_buf, (const void*)bd, len-1);    // copy the data...

Hope this helps,
George

^ permalink raw reply	[flat|nested] 12+ messages in thread
* Into the Void
@ 2005-01-26  0:09 Scott
  2005-01-26  2:18 ` Ron Michael Khu
  0 siblings, 1 reply; 12+ messages in thread
From: Scott @ 2005-01-26  0:09 UTC (permalink / raw)
  To: linux-c-programming

Years ago, I learned this trick from somebody in the C/C++ Journal, or
whatever that rag was called:

           memcpy(*data_buf,bp,len)[len] = '\0';

I get the following error:

indatax.c: In function `read_datum':
indatax.c:374: warning: dereferencing `void *' pointer
indatax.c:374: invalid use of void expression

and if I cast the function:

           (char *) memcpy(*data_buf,bp,len)[len] = '\0';

I get:

indatax.c: In function `read_datum':
indatax.c:374: warning: dereferencing `void *' pointer
indatax.c:374: void value not ignored as it ought to be

What aren't I understanding here? Tell me to go away if these
questions are too elementary for the list....

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-02-02 18:17 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-26 13:45 Into the Void Jeff.Fellin
2005-01-26 16:11 ` Scott
2005-01-27  4:02   ` Ron Michael Khu
2005-01-27 17:01     ` Scott
  -- strict thread matches above, loose matches on Subject: below --
2005-02-02 18:17 Huber, George K RDECOM CERDEC STCD SRI
2005-02-01 15:32 Huber, George K RDECOM CERDEC STCD SRI
2005-02-02 12:15 ` Glynn Clements
2005-01-27 17:58 Huber, George K RDECOM CERDEC STCD SRI
2005-01-28  4:36 ` Amit Dang
2005-01-26 16:02 Huber, George K RDECOM CERDEC STCD SRI
2005-01-26  0:09 Scott
2005-01-26  2:18 ` Ron Michael Khu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).