Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Allocated memory

Reply
Thread Tools

Allocated memory

 
 
john
Guest
Posts: n/a
 
      06-07-2004
I have a similar code to the following, here is the simplified version. I
didn't compile and run the following code, so don't worry about the syntax.
My question is I memcpy a larger data (10Byte) to a smaller one (1B),
however i can still access all the data (ref. to printf in the code). I
suppose the stack size is usually big enough for this to happen (tell me
otherwise). But what's the potential problem here?
I thought it might screw up the pointer, mStruct.buf. But it's not. Is this
legal? if not, why it's compliable? any problem here? thanks a lot.

char tenChars[10];
struct myStruct
{
int a;
char oneChar[1];
char * buf;
}

main()
{
struct myStruct mStruct;
char tenChar[10];

memset( tenChar, 1, 10);
memcpy( mStruct.oneChar, &tenChars, 10);
for (i=0; i<10; i++)
printf("%c\n", buf[i];
}


----------------------------------
remove "(n.o---s.p.a.m)" to reply




 
Reply With Quote
 
 
 
 
Stephen Sprunk
Guest
Posts: n/a
 
      06-08-2004
"john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message
news:%r6xc.32548$(E-Mail Removed)...
> I have a similar code to the following, here is the simplified version. I
> didn't compile and run the following code, so don't worry about the

syntax.
> My question is I memcpy a larger data (10Byte) to a smaller one (1B),
> however i can still access all the data (ref. to printf in the code). I
> suppose the stack size is usually big enough for this to happen (tell me
> otherwise). But what's the potential problem here?


Your code writes past the end of mStruct.oneChar, which is undefined
behavior. On some systems it might work, but on my system it dumps core --
just like I expected.

> I thought it might screw up the pointer, mStruct.buf. But it's not. Is

this
> legal? if not, why it's compliable? any problem here? thanks a lot.


Just because it's undefined behavior doesn't mean it won't compile. Most C
translators will give you enough rope to hang yourself without so much as a
warning; taking care not to do so is _your_ responsibility, not the
translator's.


Various errors fixed below:

> char tenChars[10];
> struct myStruct
> {
> int a;
> char oneChar[1];
> char * buf;
> }


};

> main()


int main()

> {
> struct myStruct mStruct;
> char tenChar[10];


int i;

> memset( tenChar, 1, 10);
> memcpy( mStruct.oneChar, &tenChars, 10);
> for (i=0; i<10; i++)
> printf("%c\n", buf[i];


printf("%c\n", mStruct.buf[i]);

> }



S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

 
Reply With Quote
 
 
 
 
Tim Orbaker
Guest
Posts: n/a
 
      06-08-2004


john wrote:
> I have a similar code to the following, here is the simplified version. I
> didn't compile and run the following code, so don't worry about the syntax.
> My question is I memcpy a larger data (10Byte) to a smaller one (1B),
> however i can still access all the data (ref. to printf in the code). I
> suppose the stack size is usually big enough for this to happen (tell me
> otherwise). But what's the potential problem here?
> I thought it might screw up the pointer, mStruct.buf. But it's not. Is this
> legal? if not, why it's compliable? any problem here? thanks a lot.


In your example below, it is legal (see further note), but it's
exceedingly bad form and may not work on all compilers.

The reason this works is that myStruct is typically 12 bytes in size on
a 32-bit machine and 24 bits in size on a 64-bit machine. This is
structure padding. By aligning the fields in memory to match the machine
word size, considerable(?) performance is gained.

>
> char tenChars[10];
> struct myStruct
> {
> int a;
> char oneChar[1];
> char * buf;
> }
>
> main()
> {
> struct myStruct mStruct;
> char tenChar[10];
>
> memset( tenChar, 1, 10);


Change this to: strncpy( tenChar, "0123456789", 10);

> memcpy( mStruct.oneChar, &tenChars, 10);
> for (i=0; i<10; i++)
> printf("%c\n", buf[i];
> }
>


Now, printing mStruct.oneChar[0] should show you either 4, or 8,
depending upon your machine word size. Try the following (the results
will vary based upon the endian-ness of your machine):

printf( "%08x\n", mStruct.a ); // Should be something like 30313233
printf( "%08x\n", (unsigned) mStruct.buf ); // Should be like 383900??


>
> ----------------------------------
> remove "(n.o---s.p.a.m)" to reply
>
>
>
>


 
Reply With Quote
 
Thomas Matthews
Guest
Posts: n/a
 
      06-08-2004
john wrote:
> I have a similar code to the following, here is the simplified version. I
> didn't compile and run the following code, so don't worry about the syntax.
> My question is I memcpy a larger data (10Byte) to a smaller one (1B),
> however i can still access all the data (ref. to printf in the code). I
> suppose the stack size is usually big enough for this to happen (tell me
> otherwise). But what's the potential problem here?


The problem is that you are moving data from a large container to
a very small container. Just as reality and physics state, you have
created undefined behavior. The container may overflow, it may break,
it may explode.

Why are you doing this?


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

 
Reply With Quote
 
Darrell Grainger
Guest
Posts: n/a
 
      06-08-2004
On Tue, 8 Jun 2004, john wrote:

> I have a similar code to the following, here is the simplified version. I
> didn't compile and run the following code, so don't worry about the syntax.


Why not take the few seconds to compile the code and try it. If it fails
to work then you don't even need to ask this question here. If it does
succeed then you can post code you know appears to be funcitonal.

> My question is I memcpy a larger data (10Byte) to a smaller one (1B),
> however i can still access all the data (ref. to printf in the code). I
> suppose the stack size is usually big enough for this to happen (tell me
> otherwise). But what's the potential problem here?


It is undefined behaviour. Anything can happen.

> I thought it might screw up the pointer, mStruct.buf. But it's not. Is this
> legal? if not, why it's compliable? any problem here? thanks a lot.


How do you know it is not trashing mStruct.buf? There is nothing in your
code example to show it is not.

> char tenChars[10];
> struct myStruct
> {
> int a;
> char oneChar[1];
> char * buf;
> }
>
> main()
> {
> struct myStruct mStruct;
> char tenChar[10];
>
> memset( tenChar, 1, 10);
> memcpy( mStruct.oneChar, &tenChars, 10);
> for (i=0; i<10; i++)
> printf("%c\n", buf[i];
> }


I'm unclear if you intended to create the global array tenChars and the
local array tenChar. It could be on your implementation that this excessive
allocation of memory is helping you. You are actually trashing the tenChar
memory.

I'm actually having to make assumptions about what you intended. I would
believe it safe to assume the reference to buf[i] should actually be
mStruct.buf[i]. I wonder why you are initializing tenChar with the memset
and then copying the contents of tenChars (an uninitialized array) to
mStruct.oneChar, using memcpy.

I created the following program that does compile:

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

char tenChars[] = "123456789";
struct myStruct {
int a;
char oneChar[1];
char *buf;
};

int main(void)
{
struct myStruct mStruct;
char tenChar[] = "123456789";

/* inialize the structure */
mStruct.a = 0xdead;
mStruct.buf = tenChar;
printf("a: %x\tbuf: %p\n", mStruct.a, mStruct.buf);

/* trash memory */
memcpy(mStruct.oneChar, tenChars, 10);

/* see that memory has been trashed */
printf("a: %x\tbuf: %p\n", mStruct.a, mStruct.buf);

return 0;
}

When I run it on my system, the value of mStruct.buf changes after the memcpy.
Dereferencing mStruct.buf after the memcpy will definitely cause undefined
behaviour. Since I have one instance that it fails to function as required,
I would never do something like this.

--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
JKop
Guest
Posts: n/a
 
      06-08-2004
john posted:

> I have a similar code to the following, here is the simplified version.
> I didn't compile and run the following code, so don't worry about the
> syntax. My question is I memcpy a larger data (10Byte) to a smaller one
> (1B), however i can still access all the data (ref. to printf in the
> code). I suppose the stack size is usually big enough for this to
> happen (tell me otherwise). But what's the potential problem here?




int *pJack = 0x9983;

*pJack = 42;



-JKop
 
Reply With Quote
 
john
Guest
Posts: n/a
 
      06-09-2004
First of all, I found this from the software I'm working on. It's not
written by me, so do not ask me why I wrote this.
The code on the OP is just something I written from scratch to illustrate
the whole thing. I don't want to copy the exact code, because it's not
important and it might be distracting, and will be a long post (seems
unavoidable now ). So do not tell me the correction of code like Stephen
and Darrell did. thanks anyway.

I did made a mistake in the code (maybe is this causing the confusion,
really sorry about that) which I intended to printf the oneChar instead of
buf on the last line. as follows:
printf("%c\n", mStruct.oneChar[i];
the purpose is to tell you that I can access all the data copied from
tenChar to oneChar. so the print out will be 10 ones as "1111111111".

I put char *buf just to illustrate this pointer has NOT been corrupted due
to stamping over by that "overflow copy". If I re-write it again, it will be
like this (the data vars before the main() are the same):

main()
{
struct myStruct mStruct;
char tenChar[10];
int d;

mStruct.buf = &d;
printf("%x\n", mStruct.buf); // let's say this will print "801a34bc"

memset( tenChar, 1, 10);
memcpy( mStruct.oneChar, &tenChars, 10);
for (i=0; i<10; i++)
printf("%c\n", mStruct.oneChar[i]; // this will print "1111111111"

printf("%x\n", mStruct.buf); // this will print "801a34bc"
}

As i said, I'm working for other people, and I can't tell them this is a bug
because it doesn't do anything wrong. so I need to know how I can generate a
fault with this, so that I can flag this as a bug and request a fix. that's
why I was asking what are the potential problems, as I can use these to
generate some faults. hopefully.

I will answer each post separately.

IMPORTANT BIT:
Remember the whole idea/point/question is copying a larger array to a
smaller one, what's potential problems?
give some examples or code so that i can reproduce, be it crashing, data
corruptions, whatever. Saying "undefine behaviour" is not what I lookin for,
because I know that.

"john" <john2000(n.o---s.p.a.m)@blueyonder.co.uk> wrote in message
news:%r6xc.32548$(E-Mail Removed)...
> I have a similar code to the following, here is the simplified version. I
> didn't compile and run the following code, so don't worry about the

syntax.
> My question is I memcpy a larger data (10Byte) to a smaller one (1B),
> however i can still access all the data (ref. to printf in the code). I
> suppose the stack size is usually big enough for this to happen (tell me
> otherwise). But what's the potential problem here?
> I thought it might screw up the pointer, mStruct.buf. But it's not. Is

this
> legal? if not, why it's compliable? any problem here? thanks a lot.
>
> char tenChars[10];
> struct myStruct
> {
> int a;
> char oneChar[1];
> char * buf;
> }
>
> main()
> {
> struct myStruct mStruct;
> char tenChar[10];
>
> memset( tenChar, 1, 10);
> memcpy( mStruct.oneChar, &tenChars, 10);
> for (i=0; i<10; i++)
> printf("%c\n", buf[i];
> }
>
>
> ----------------------------------
> remove "(n.o---s.p.a.m)" to reply
>
>
>
>






 
Reply With Quote
 
john
Guest
Posts: n/a
 
      06-09-2004
Please read my reply to the OP first!

"Thomas Matthews" <(E-Mail Removed)> wrote in
message news:1mjxc.2351$e%(E-Mail Removed) m...
> The problem is that you are moving data from a large container to
> a very small container. Just as reality and physics state, you have
> created undefined behavior. The container may overflow, it may break,
> it may explode.
>

If you know the scenarios, criteria that can cause overflow, or break, or
explode in this case, that would be very helpful.

> Why are you doing this?
>

As I explained earlier in my reply, I didn't do this, I found this. but it
didn't give me trouble, that troubles me



 
Reply With Quote
 
john
Guest
Posts: n/a
 
      06-09-2004
Please read my reply to the OP first!

"Tim Orbaker" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

> In your example below, it is legal (see further note), but it's
> exceedingly bad form and may not work on all compilers.
>

in this case, it works on mine

> The reason this works is that myStruct is typically 12 bytes in size on
> a 32-bit machine and 24 bits in size on a 64-bit machine. This is
> structure padding. By aligning the fields in memory to match the machine
> word size, considerable(?) performance is gained.
>

maybe it's a bad example, can you change the 10 bytes to 100 bytes, like
this:
char tenChars[100];
Please don't take this as a wind up, the actual code that I'm working on
copy more than 100 bytes. The reason I chose 10 bytes is no reason really,
mainly to simplify the code, and the whole point is to illustrate copying
from larger to smaller anyway.

Nevertheless, you have some interesting point there. I will try this out.
Why memcpy oneChar will override mStruct.a? because you said
> printf( "%08x\n", mStruct.a ); // Should be something like 30313233



> >
> > char tenChars[10];
> > struct myStruct
> > {
> > int a;
> > char oneChar[1];
> > char * buf;
> > }
> >
> > main()
> > {
> > struct myStruct mStruct;
> > char tenChar[10];
> >
> > memset( tenChar, 1, 10);

>
> Change this to: strncpy( tenChar, "0123456789", 10);
>
> > memcpy( mStruct.oneChar, &tenChars, 10);
> > for (i=0; i<10; i++)
> > printf("%c\n", buf[i];
> > }
> >

>
> Now, printing mStruct.oneChar[0] should show you either 4, or 8,
> depending upon your machine word size. Try the following (the results
> will vary based upon the endian-ness of your machine):
>
> printf( "%08x\n", mStruct.a ); // Should be something like 30313233
> printf( "%08x\n", (unsigned) mStruct.buf ); // Should be like 383900??
>
>
> >
> > ----------------------------------
> > remove "(n.o---s.p.a.m)" to reply
> >
> >
> >
> >

>





 
Reply With Quote
 
john
Guest
Posts: n/a
 
      06-09-2004
Please read my reply to the OP first!

"Stephen Sprunk" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) s.com...

> Your code writes past the end of mStruct.oneChar, which is undefined
> behavior. On some systems it might work, but on my system it dumps

core --
> just like I expected.


what causing the core dump on your system? afaik, there are few criteria for
this, accessing a null pointer is on of them. I mean you should answer only
if you know, it's a bit too difficullt job to find out anyway.




 
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
How to check memory size allocated to JVM? Laura Heinzmann Java 1 02-16-2005 04:37 AM
Dynamically Allocated Memory vs. Statically allocated Memory csnerd@gmail.com C++ 5 12-09-2004 01:44 AM
Memory allocated to an object of a class C++fan C++ 4 01-07-2004 02:53 AM
How do I know if memory is already allocated? Kjell Arne Johansen C++ 8 09-02-2003 06:12 AM
Duplicate memory allocated by IndexedTriangleArray Duncan Java 0 07-21-2003 07:25 PM



Advertisments