By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,434 Members | 1,854 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,434 IT Pros & Developers. It's quick & easy.

A possible memory overwriting.

P: n/a
Recently I came across a code which is quite similar to one shown
below:

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

typedef struct node
{
int data;
int arr[10];
struct node *next;
} node;

int main(void)
{
node block;
memset( &block, 0 , sizeof(block) );
printf("Main exiting...\n");
return 0;
}

In the above code, the memset function will make the "sizeof(block)
elements" in memory being pointed by &block equal to zero. But, isn't
the memset function overwriting the memory being pointed by &block
since the memory beyond the one being pointed by &block might be
belonging to something else?
Please help me to pin-point my mistake.

Nov 15 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
ja**********@yahoo.com wrote:
typedef struct node
{
int data;
int arr[10];
struct node *next;
} node;
<snip>
node block;
memset( &block, 0 , sizeof(block) );
<snip>
In the above code, the memset function will make the "sizeof(block)
elements" in memory being pointed by &block equal to zero.
Yes.
But, isn't
the memset function overwriting the memory being pointed by &block
Yes.
since the memory beyond the one being pointed by &block might be
belonging to something else?
The memory &block points to is block, which of course belongs to you.
The only problem with the memset() call is that it probably expects to
set next to NULL - it probably will work, but all-bits-0 is not
guaranteed to be a null pointer.
Please help me to pin-point my mistake.


You didn't make one in the code you posted.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 15 '05 #2

P: n/a
ja**********@yahoo.com wrote:

# In the above code, the memset function will make the "sizeof(block)
# elements" in memory being pointed by &block equal to zero. But, isn't

sizeof block bytes, not elements.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
So basically, you just trace.
Nov 15 '05 #3

P: n/a

SM Ryan wrote:
ja**********@yahoo.com wrote:

# In the above code, the memset function will make the "sizeof(block)
# elements" in memory being pointed by &block equal to zero. But, isn't

sizeof block bytes, not elements.


But the code for memset() indicates that it is sizeof(block)
"elements" and not "bytes" and in that case the program should crash
beacuse of the overwriting of the return address.
void *memset(void *s, register int c, register size_t n)
{
register char *s1 = *(char*)s;

while( n>0 )
{
*s1++ = c;
--n;
}

return s1;
}

Nov 15 '05 #4

P: n/a
ja**********@yahoo.com wrote:
SM Ryan wrote:
ja**********@yahoo.com wrote:

# In the above code, the memset function will make the "sizeof(block)
# elements" in memory being pointed by &block equal to zero. But, isn't

sizeof block bytes, not elements.
But the code for memset()


What code for memset()? There is no _the_ code for memset(). There is only
_the_ specification for memset(), and it states this:

# The memset function copies the value of c (converted to an unsigned char)
# into each of the first n characters of the object pointed to by s.
^^^^^^^^^^

Note: characters, so bytes. Not elements. It gets a void pointer, anyway, so
how is it to know in the first place how large an "element" is for the
original pointer?
void *memset(void *s, register int c, register size_t n)
{
register char *s1 = *(char*)s;

while( n>0 )
{
*s1++ = c;
--n;
}

return s1;
}


This is _a_ possible implementation for memset(), and it copies into the
first n characters (ergo bytes), not "elements", whatever they are.
Note, btw, that it converts c into a char, not explicitly into an unsigned
char. This is only valid for some (although many) implementations, not for
all.

Richard
Nov 15 '05 #5

P: n/a
Richard Bos wrote:

ja**********@yahoo.com wrote:
void *memset(void *s, register int c, register size_t n)
{
register char *s1 = *(char*)s;

This is _a_ possible implementation for memset(),


No, it isn't.
1 The pointer s1 is assigned a char value
instead of a pointer value.
2 The type of s1 should be (unsigned char *).

--
pete
Nov 15 '05 #6

P: n/a
pete <pf*****@mindspring.com> wrote:
Richard Bos wrote:

ja**********@yahoo.com wrote:

void *memset(void *s, register int c, register size_t n)
{
register char *s1 = *(char*)s;

This is _a_ possible implementation for memset(),


No, it isn't.
1 The pointer s1 is assigned a char value
instead of a pointer value.
2 The type of s1 should be (unsigned char *).


*Sigh* Yes. As I noted in the next sentence. So this is _a_ possible way
to code memset() for many, but not all, C implementations. As I noted.

Richard
Nov 15 '05 #7

P: n/a
Richard Bos wrote:

pete <pf*****@mindspring.com> wrote:
Richard Bos wrote:

ja**********@yahoo.com wrote:
> void *memset(void *s, register int c, register size_t n)
> {
> register char *s1 = *(char*)s;

This is _a_ possible implementation for memset(),


No, it isn't.
1 The pointer s1 is assigned a char value
instead of a pointer value.


*Sigh* Yes. As I noted in the next sentence.
So this is _a_ possible way
to code memset() for many, but not all, C implementations. As I noted.


No!!!
*(char*)s
should be
s

Those are two completely different initializations.
In order for the first one to work, the first byte
of the target object would have to contain a char value
that converts to a pointer to itself,
which besides being implementation defined,
is super extremely unlikely.
memset does not depend upon the value of the first byte
of the taget object, which is what (*(char*)s) is.

--
pete
Nov 15 '05 #8

P: n/a
ja**********@yahoo.com wrote:
#
# SM Ryan wrote:
# > ja**********@yahoo.com wrote:
# >
# > # In the above code, the memset function will make the "sizeof(block)
# > # elements" in memory being pointed by &block equal to zero. But, isn't
# >
# > sizeof block bytes, not elements.
#
# But the code for memset() indicates that it is sizeof(block)
# "elements" and not "bytes" and in that case the program should crash
# beacuse of the overwriting of the return address.

You're casting to a character pointer, so its elements are
bytes. But in something like

int x[2]; memset(x,0,sizeof x);

Assuming 4-byte ints, sizeof x is 8, and memset clears 8 bytes,
not 8 ints.

# void *memset(void *s, register int c, register size_t n)
# {
# register char *s1 = *(char*)s;
#
# while( n>0 )
# {
# *s1++ = c;
# --n;
# }
#
# return s1;
# }
#
#
#

--
SM Ryan http://www.rawbw.com/~wyrmwif/
So basically, you just trace.
Nov 15 '05 #9

P: n/a
SM Ryan wrote:

ja**********@yahoo.com wrote:
#
# SM Ryan wrote:
# > ja**********@yahoo.com wrote:
# >
# > # In the above code, the memset function will make the
# > # "sizeof(block)
# > # elements" in memory being pointed
# > # by &block equal to zero. But, isn't
# >
# > sizeof block bytes, not elements.
#
# But the code for memset() indicates that it is sizeof(block)
# "elements" and not "bytes" and in that case the program should crash
# beacuse of the overwriting of the return address.

You're casting to a character pointer, so its elements are
bytes. But in something like
It's much more fucked up than that.
The value, >>>not the address<<<,
of the first byte of the target is being assigned to s1.
Even if it were to return s instead of s1, it still wouldn't work.
int x[2]; memset(x,0,sizeof x);

Assuming 4-byte ints, sizeof x is 8, and memset clears 8 bytes,
not 8 ints.

# void *memset(void *s, register int c, register size_t n)
# {
# register char *s1 = *(char*)s;
#
# while( n>0 )
# {
# *s1++ = c;
# --n;
# }
#
# return s1;
# }


void *mem_set(void *s, int c, size_t n)
{
unsigned char *p = s;

while (n-- != 0) {
*p++ = (unsigned char)c;
}
return s;
}

--
pete
Nov 15 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.