low-level question

J

jesso

I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?
2. Explain in detail.
3. How could you prevent this outcome without changing the code?


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

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?

The program does not /necessarily/ output a 0. The program invokes
undefined behaviour, and /any/ output (or lack of output) is valid.
2. Explain in detail.

buf is defined as an array of 4 characters (char buf[4];)
However, the program uses the standard function strcpy() to modify the
contents of this array. The string given to strcpy() to copy into buf
consists of 4 characters, /plus/ a string-termination character of \0.

When strcpy() copies the initialization string into buf, it will copy 4
characters (which will fit into buf, as buf is defined as a 4 character
array), and will terminate the copied string with a \0 character. This
terminating character will not fit within the confines of buf (which is
already full), and will be written to some other area of memory.

Assuming specific environmental and compiler characteristics, this \0
character /may/ be written in such a manner as to overwrite the
significant bits of the ii variable, setting ii to 0.

*However*, there is no guarantee that this can happen. It would require
- - ii to start /immediately/ after buf in memory, and
- - ii to be stored as a 'little-endian' binary value

There is no guarantee, from the code and details provided, that the
compiler will
- - align ii to a 4-byte boundary,
- - order ii to /follow/ buf in memory, or
- - store int values as little-endian binary numbers
3. How could you prevent this outcome without changing the code?

Don't run the program.
#include <stdio.h>
#include <string.h>

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}


- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDFFRJagVFX4UWr64RAgk8AJ90VvPuywZWEnLXgjgDM0bd/udhRQCgvu3U
+cNqEFIlcQbqc1J8T1BxITo=
=Jp1t
-----END PGP SIGNATURE-----
 
Z

Zara

jesso said:
char buf[ 4 ];

strcpy( buf, "AAAA" );
Here, you are copying 5 bytes in 4 byte space (remeber the terminating
null byte). So, you may have *any* unexpected behaviour. For instance,
printing a zero. But it could have been an expeption, a segment
violation, or your computer connecting to some web porn site.
 
R

Robert Gamble

jesso said:
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?
2. Explain in detail.
3. How could you prevent this outcome without changing the code?


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

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}

It is undefined behavior in C because you are writing past the end of
an arry ("AAAA" is 5 characters, buf is 4). Since it is undefined
behavior, anything can happen. There might be certain behaviors that
are more likely to occur than others due to nuances of your specific
platform but I can't think of anything plausible that would account for
the behavior suggested by the question.

If ii was char then it might be plausible for ii to be located
immediately following the space allocated for buf in which case the
'\0' at the end of the string being copied may be written to ii making
it's value 0. This is still undefined behavior according to the
Standard though and would be completely implementation dependant.

Is this for a general C class or a compiler construction/assembly/etc
class?

Robert Gamble
 
G

Gordon Burditt

I couldn't get this on a midterm. Darn!
Anyone want to help?

1. Why does the following program output a 0?

Who says it does? The standard certainly doesn't require it.
2. Explain in detail.

There are no guarantees that if you overflow an array, it will overflow
into the variable declared immediately after it. (On some linkers,
it will overflow into the variable *alphabetically* after it, given
that they're both auto variables in the same function.) There are also
no guarantees that this code is running on an endian machine.
3. How could you prevent this outcome without changing the code?

Don't run it? Run on a non-endian machine? Kill the author
of the code?
#include <stdio.h>
#include <string.h>

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}
 
J

jesso

I had this question years ago on a midterm and just seen it on a job
posting.

The company said if you answer the question intelligently then u will
get an interview.

I am not applying, but was curious on what the answers were.

It is undefined behaviour. By saying " Why does the following program
output a 0?", must be a trick.
 
J

jesso

From the ad:

Still I wonder what they are looking for with:
"How could you prevent this outcome without changing the code?"

This is an
"
ASM/C Developer/Analyst - Linux platform

Developer/analyst with strong skills in assembler and C on Linux.
"

=============

QUIZ QUESTION:

If you can answer this question intelligently, you are guaranteed an
interview (please remember to attach your resume):

Why does the following program output a 0? Explain in detail. How
could you prevent this outcome without changing the code?

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
int main(int argc, char *argv[])
{
int i = 1;
char buf[4];
strcpy(buf, "AAAA");
printf("%d\n", i);
return 0;
}
 
M

Mark McIntyre

Why does the following program output a 0?

Because of how that particular compiler or OS or hardware implements
undefined behaviour, vis writing off the end of an array.
Explain in detail.

This isn't a C question, its a hardware / OS / compiler question.
How could you prevent this outcome without changing the code?

Run on different hw/sw which handles the UB differently.
Compile with special "don't allow UB" options.
Don't run the app at all - it has a serious bug.
 
M

Martin Ambuhl

jesso said:
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?

It is an accident. It could return anything. Buffer overflows don't
result in well-defined behavior.
2. Explain in detail.

See above.
3. How could you prevent this outcome without changing the code?

You can't fix code without changing it. What are you smoking? A
minimum change to the code (not allowed by the conditions) is to declare
char buf[5]; /* Those spaces around '4' seem to be a clue. */

[broken code follows]

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

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}
 
B

Bryan Donlan

jesso said:
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?

Undefined behavior. strcpy writes five characters into a four-character
buffer ('A'x4, then a 0). Of course, it might not produce a zero. It might
produce a 1, 42, -999, 'ducks? thanks', erase your harddrive, or simply
crash.

In fact, on my system it produces a one with -O1 or higher, so the question
truly is nonsensical.
2. Explain in detail.
3. How could you prevent this outcome without changing the code?

You can't. With the code as is, it will always invoke undefined behavior. No
wonder you couldn't get this on your midterm; it asks the impossible.
#include <stdio.h>
#include <string.h>

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ]; Make this: char buf[5];

strcpy( buf, "AAAA" );
Or make the string three characters or less.
 
K

Keith Thompson

Robert Gamble said:
jesso said:
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?
2. Explain in detail.
3. How could you prevent this outcome without changing the code?


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

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}

It is undefined behavior in C because you are writing past the end of
an arry ("AAAA" is 5 characters, buf is 4). Since it is undefined
behavior, anything can happen. There might be certain behaviors that
are more likely to occur than others due to nuances of your specific
platform but I can't think of anything plausible that would account for
the behavior suggested by the question.

If ii is allocated just after the end of buf, and if the platform uses
a little-endian representation for int, the '\0' of "AAAA" could
plausibly be written over the low-order byte of ii, causing it to be
set to 0.
 
R

Robert Gamble

Keith said:
Robert Gamble said:
jesso said:
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?
2. Explain in detail.
3. How could you prevent this outcome without changing the code?


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

int
main( int argc, char *argv[] )
{
int ii = 1;
char buf[ 4 ];

strcpy( buf, "AAAA" );

printf( "%d\n", ii );

return 0;
}

It is undefined behavior in C because you are writing past the end of
an arry ("AAAA" is 5 characters, buf is 4). Since it is undefined
behavior, anything can happen. There might be certain behaviors that
are more likely to occur than others due to nuances of your specific
platform but I can't think of anything plausible that would account for
the behavior suggested by the question.

If ii is allocated just after the end of buf, and if the platform uses
a little-endian representation for int, the '\0' of "AAAA" could
plausibly be written over the low-order byte of ii, causing it to be
set to 0.

Yep, I was being a little bit narrow-minded when I posted that. I
realized this shortly after I posted and then saw that Lew Pitcher
covered this case so I didn't feel the need to amend my post.

Robert Gamble
 
P

Peter Shaggy Haywood

Groovy hepcat jesso was jivin' on 30 Aug 2005 05:30:18 -0700 in
comp.lang.c.
low-level question's a cool scene! Dig it!
I couldn't get this on a midterm. Darn!

Sure. And it's not your homework you want us to do for you, or
anything.
Anyone want to help?

1. Why does the following program output a 0?

For the same reason it might make the computer reach out and smack
you at any time.
2. Explain in detail.

When you invoke undefined behaviour, anything is allowed to happen.
This includes the incredibly mundane, such as outputting 0, and the
downright bizzarre, like making the computer reach out and slap you.
3. How could you prevent this outcome without changing the code?

Don't run the compiled program.

[Snip code invoking undefined behaviour.]

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
J

Johan Borkhuis

Bryan said:
tedu wrote:




It's still undefined behavior, and can do whatever it wants.

Then how about this:
compile with -D"strcpy(a,b)"="ii"

PS
I would have suggested this: -D"strcpy(a,b)"="strncpy((a),(b),sizeof(b))"
but that give problems with string.h, which can be avoided by doing the
following:
touch string.h
touch stdio.h
gcc -nostdinc -isystem . -D"strcpy(a,b)"="strncpy((a),(b),sizeof(a))" \
-save-temps -o test test.c
but this is way to compiler and OS specific for the clc newsgroup :)

Kind regards,
Johan

--
o o o o o o o . . . _____J_o_h_a_n___B_o_r_k_h_u_i_s___
o _____ || http://www.borkhuis.com |
.][__n_n_|DD[ ====_____ | (e-mail address removed) |
>(________|__|_[_________]_|________________________________|
_/oo OOOOO oo` ooo ooo 'o!o!o o!o!o`
== VxWorks FAQ: http://www.xs4all.nl/~borkhuis/vxworks/vxworks.html ==
 
D

doodoosy

3. How could you prevent this outcome without changing the code?

Plug off your monitor
 
R

Randy Howard

jesso wrote
(in article
I couldn't get this on a midterm. Darn!

Anyone want to help?

1. Why does the following program output a 0?

Your professor needs to be fired.
2. Explain in detail.

Reading through the various responses already posted should be
more than enough ammunition to back up my assertion above.
If you got this question 'wrong' on your midterm, you should be
able to make the claim that the question was bogus and
completely inappropriate, especially the first question about
the output being 0 for such an exam, not to mention the
ludicrous notion that it can be fixed without changing the code.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top