Allocated memory

J

john

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;
}
 
S

Stephen Sprunk

john said:
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;


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


S
 
T

Tim Orbaker

john said:
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;
}


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??
 
T

Thomas Matthews

john said:
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
 
D

Darrell Grainger

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'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 should actually be
mStruct.buf. 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.
 
J

JKop

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
 
J

john

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;
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; // 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 said:
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;
}
 
J

john

Please read my reply to the OP first!

Thomas Matthews said:
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 :(
 
J

john

Please read my reply to the OP first!

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;
}


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??
 
J

john

Please read my reply to the OP first!

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.
 
J

john

Please read my reply to the OP first!

Darrell Grainger said:
On Tue, 8 Jun 2004, john wrote:

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.
Hope you understand now. the code written here is not important. The actual
code compiled and runs ok (maybe it's not ok, this is what I'm trying to
find out).
It is undefined behaviour. Anything can happen.
If you can give some examples that you know of, that would be great.
How do you know it is not trashing mStruct.buf? There is nothing in your
code example to show it is not.
I should printf the "buf" in the code to clarify this.
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.
Oh, this is new to me. I will read the rest first.... now I have read the
rest. but I still dont get it as how tenChar will get trashed. Will run the
code and see.
I'm actually having to make assumptions about what you intended. I would
believe it safe to assume the reference to buf should actually be
mStruct.buf.

correct assumption. But this is a mistake, I actually want to print
mStruct.oneChar to illustrate I can access all the copied data.
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.
just to prove I can access all the copied data, so the print out will be
"1111111111".
I created the following program that does compile:
no need for this, as it's only for illustration.
#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.
 
S

Stephen Sprunk

john said:
Please read my reply to the OP first!



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.

When memcpy() writes past the end of mStruct.oneChar, it overwrites
mStruct.buf with 0x01010101. When main() tries to dereference
mStruct.buf to generate the argument to printf(), it accesses memory that
doesn't belong to the process and thus triggers a segfault. This is just my
analysis from reading the code, but I'll go through it with gdb if you want
proof for your employer.

My particular system is Linux 2.2.16 and gcc 2.91.66, but I'm surprised this
isn't the result on every system with memory protection. In any case, it
does invoke undefined behavior and should be considered a bug even if it
mysteriously works on some systems.

S
 
B

Barry Schwarz

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;
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()


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

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

Let's not. Most of us prefer not to depend on undefined behavior. %x
expects an int. You are passing it a pointer. If you want to print
the value of a pointer, use %p and cast the value to void*.
memset( tenChar, 1, 10);
memcpy( mStruct.oneChar, &tenChars, 10);

Since memcpy takes pointers to void, the use of &tenChars doesn't hurt
here but you really want to get in the habit of using the array name
without an & in most situations like this. While you are at it,
decide if the array name is tenChar or tenChars.
for (i=0; i<10; i++)

i is undefined.
printf("%c\n", mStruct.oneChar; // this will print "1111111111"


Not very likely. Did you try it? Each oneChar has the value
integer 1. This is considerably different than the character value
'1' which is what it would have to contain to match your comment.

By the way, why do you think the \n will not force each character to a
new line?
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

It doesn't work now. How many more faults do you need?
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?

Tell them to look at every virus they have ever relieved. Most
exploit some kind of buffer overrun, which is exactly what copying a
large array to a small one is.
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.

If you really want to be able to show them that it is broken, have
them look at the generated assembler code. If they can't read that,
then you do it and define several more variables so that some
immediately follow the short array. Initialize one of these post
array variables, print it, copy the long array to the short, then
print the post array variable again and show them the changed value.

You might also want to work on your resume since this head in the sand
style of management will not survive in the long run. Remember the
adage "those who wait for an accident before fixing anything are part
of the problem, not part of the solution."

You have no idea how much padding the compiler decided to insert
between oneChar and buf.

On my system when I ran your code, buf printed two different values:
65fddc and 1010101. It did exactly what you expected. Why it doesn't
on your system is something only you can determine.

You have the same problems copying the large array into the smaller
one not defining i. Then you try to dereference buf when it was never
initialized.

I think there used to be a contest here about who could cram the most
undefined behavior into the shortest code. I don't think you are near
the record but if you practice...
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;
}




<<Remove the del for email>>
 
C

Chris Torek

The code [in my original post] 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 ...
I did made a mistake in the [original example posting] code
[followed by a new example that does not compile and clearly
is not the problematic code].

I think this deserves a parable. :)

A man showed up at a veterinary office with a Persian house cat.
"My pet is sick, can you help him?"

The doctor examined the cat and told the man that the problem was
simply a hairball, and that grooming and petromalt would typically
solve the problem.

"Oh no," the man exclaimed. "The problem isn't hairballs!"

"I think it is," replied the vet. "This cat has no fever, and
no signs of anything other than mild dehydration."

"But you see," explained the main, "this isn't even my pet -- I
have an elephant! I didn't bring him in because he's too big to
fit in my car!"
 
B

Branimir Maksimovic

john said:
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.
Just explain behavior of following program :
include <stdio.h>

typedef struct Test{
int one[1];
volatile int size;
int* buf;
} Test;

void initTest(Test* t, int size)
{
t->size = size;
t->buf = t->one;
for(int i=0;i<t->size;++i)t->one=i;
}

void printTest(Test* t)
{
for(int i = 0; i<t->size; ++i)
{
printf("%d\n",t->one);
}
printf("%p %p %d\n",(void*)t->one,(void*)t->buf,t->size);
}

int main(void)
{
Test t;
initTest(&t, 1000);
printTest(&t);
return 0;
}

Greetings, Bane.
 
C

CBFalconer

Branimir said:
.... snip ...

Just explain behavior of following program :
include <stdio.h>
.... snip code ...

There is no explanation. It exhibits undefined behaviour, so it
can do anything at all, including committing rape, arson, battery,
and lies.

Do not post C to c.l.c++, nor C++ to c.l.c.
 
A

Alan Johnson

CBFalconer said:
There is no explanation. It exhibits undefined behaviour, so it
can do anything at all, including committing rape, arson, battery,
and lies.

I'm sorry. Discussion of MSVC++ is off-topic here. ;-)

Alan
 
J

john

Actually you didn't tell the whole story, the more complete story is as
followed:

Before this man went to the vet with his cat. He actually did bring his
elephant to lots of vet clinics. but he always get refused. Those vets don't
even want to entertain him, just told this man we don't take elephants.

Chris Torek said:
The code [in my original post] 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 ...
I did made a mistake in the [original example posting] code
[followed by a new example that does not compile and clearly
is not the problematic code].

I think this deserves a parable. :)

A man showed up at a veterinary office with a Persian house cat.
"My pet is sick, can you help him?"

The doctor examined the cat and told the man that the problem was
simply a hairball, and that grooming and petromalt would typically
solve the problem.

"Oh no," the man exclaimed. "The problem isn't hairballs!"

"I think it is," replied the vet. "This cat has no fever, and
no signs of anything other than mild dehydration."

"But you see," explained the main, "this isn't even my pet -- I
have an elephant! I didn't bring him in because he's too big to
fit in my car!"
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to
spammers.
 
B

Branimir Maksimovic

CBFalconer said:
... snip code ...

There is no explanation. It exhibits undefined behaviour, so it
can do anything at all, including committing rape, arson, battery,
and lies.

Yes it is undefined behavior, but... we can assume that
arrays in C and C++ are laid in memory contiguously.
Variable of type "volatile int", follows array of int,
so we can assume that compiler will include side effect of buffer
overrunning, resulting that value in *that* variable, will be visible
in for loop (not cached), so program will not crash.:)
How's that different from struct hacks which are widely spread
around the globe?

typedef struct Hack{
// some elements
char string[1];
} Hack;

.....
const char* tmp = "Some thing";
Hack* pHack = malloc(sizeof(Hack)+strlen(tmp));
strcpy(pHack->string,tmp);
.....
Do not post C to c.l.c++, nor C++ to c.l.c.
I thought that program will compile fine with both c++ and c99
compilers. :) which part (of snipped code)is not C or C++?

Greetings, Bane.


P.S. this is just counter example, that is undefined behavior that
"works". Perhaps OP's example is similar to struct hack but
he haven't posted (or didn't understand) actual code.
 
C

Christian Bau

"Branimir Maksimovic said:
CBFalconer said:
... snip code ...

There is no explanation. It exhibits undefined behaviour, so it
can do anything at all, including committing rape, arson, battery,
and lies.

Yes it is undefined behavior, but... we can assume that
arrays in C and C++ are laid in memory contiguously.
Variable of type "volatile int", follows array of int,
so we can assume that compiler will include side effect of buffer
overrunning, resulting that value in *that* variable, will be visible
in for loop (not cached), so program will not crash.:)
How's that different from struct hacks which are widely spread
around the globe?

typedef struct Hack{
// some elements
char string[1];
} Hack;

....
const char* tmp = "Some thing";
Hack* pHack = malloc(sizeof(Hack)+strlen(tmp));
strcpy(pHack->string,tmp);
....
Do not post C to c.l.c++, nor C++ to c.l.c.
I thought that program will compile fine with both c++ and c99
compilers. :) which part (of snipped code)is not C or C++?

Greetings, Bane.


P.S. this is just counter example, that is undefined behavior that
"works". Perhaps OP's example is similar to struct hack but
he haven't posted (or didn't understand) actual code.

A good optimizing compiler will produce the same code for

strcpy (pHack->string, tmp);
and for
pHack->string[0] = '\0';

strcpy (pHack->string, tmp) has undefined behavior except if tmp points
to an empty string. The compiler can assume that there is no undefined
behavior and therefore tmp points to an empty string. If tmp points to
an empty string, then strcpy will just set the first array element to
'\0'. Therefore both statements are equivalent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top