Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why no segmentation fault

Reply
Thread Tools

Why no segmentation fault

 
 
Christian Christmann
Guest
Posts: n/a
 
      03-26-2006
Hi,

I'm wondering why this program does not crash with a segmentation
fault:

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

int main()
{
char *array;

array = (char*)malloc(10 * sizeof(char) );
if ( array == NULL )
exit( 0 );

strcpy( array, "11223456789\0");

printf( "\narray[11]: %c\n", array[11] )

return 0;
}

I allocate space for 10 characters on the system heap and then copy
a string of size 12 into the allocated space. Why does the program not
crash?
My understanding was so far:
malloc request some new free space on the system heap. So, first the
program memory manager is consulted to check if it is already assigned
some free space by the operating system that might be suitable for the
malloc request. If so, this memory segment is used. Otherwise, the
request is directed to the OS that provides some new free memory that
is now assigned to this program (process) and used for the malloc memory
allocation. However, when I call "strcpy( array, "11223456789\0")" I
write the first 10 characters to the allocated memory area.The
remaining 2 characters exceed the memory area I was granted access to
and are tried to be written to memory I have no write access to. That
illegal memory access should be noticed by the OS that terminates the
program with a segmentation fault.

Furthermore, my printf should also crash the program since I
illegally attempt to read from memory I have no access to.

Thank you.

Chris



 
Reply With Quote
 
 
 
 
Richard G. Riley
Guest
Posts: n/a
 
      03-26-2006
On 2006-03-26, Christian Christmann <(E-Mail Removed)> wrote:
> Hi,
>
> I'm wondering why this program does not crash with a segmentation
> fault:
>
> #include <malloc.h>
> #include <string.h>
> #include <stdio.h>
>
> int main()
> {
> char *array;
>
> array = (char*)malloc(10 * sizeof(char) );
> if ( array == NULL )
> exit( 0 );
>
> strcpy( array, "11223456789\0");
>
> printf( "\narray[11]: %c\n", array[11] )
>
> return 0;
> }
>


There is no guarentee that HW will catch all such illegal memory
accesses. There are not (always) runtime checks in languages to check
for out of bounds : it is one of the efficiencies of C that it assumes
the programmer will do the necessary bounds checks. Writing over
"illegal" memory is, I believe, "undefined" but most certainly bad
practice and most certainly will lead to nasties cropping up at a
later date if nto immediately.

I velieve it is legal to reference one unit of storage past the
"malloc"ed area, but I'm sure someone will provide more info on that.

 
Reply With Quote
 
 
 
 
santosh
Guest
Posts: n/a
 
      03-26-2006
Christian Christmann wrote:
> Hi,
>
> I'm wondering why this program does not crash with a segmentation
> fault:
>
> #include <malloc.h>


Non-standard header. Should include stdlib.h instead.

> #include <string.h>
> #include <stdio.h>
>
> int main()


A better form is int main(void)

> {
> char *array;
>
> array = (char*)malloc(10 * sizeof(char) );


Don't cast the return value of malloc. A better form of the above
statement is:
array = malloc(10 * sizeof *array);

This also has the side effect that if you ever change the base type,
(char here), you won't have to modify this statement.

> if ( array == NULL )
> exit( 0 );


exit(EXIT_SUCCESS); or exit(EXIT_FAILURE) would be more portable though
zero is always a portable return value to indicate successfull
termination.

> strcpy( array, "11223456789\0");
>
> printf( "\narray[11]: %c\n", array[11] )
>
> return 0;
> }
>
> I allocate space for 10 characters on the system heap and then copy
> a string of size 12 into the allocated space. Why does the program not
> crash?
> My understanding was so far:
> malloc request some new free space on the system heap. So, first the
> program memory manager is consulted to check if it is already assigned
> some free space by the operating system that might be suitable for the
> malloc request. If so, this memory segment is used. Otherwise, the
> request is directed to the OS that provides some new free memory that
> is now assigned to this program (process) and used for the malloc memory
> allocation. However, when I call "strcpy( array, "11223456789\0")" I
> write the first 10 characters to the allocated memory area.The
> remaining 2 characters exceed the memory area I was granted access to
> and are tried to be written to memory I have no write access to. That
> illegal memory access should be noticed by the OS that terminates the
> program with a segmentation fault.
>
> Furthermore, my printf should also crash the program since I
> illegally attempt to read from memory I have no access to.


Your program writes past the end of the array and doing so, invokes
undefined behaviour. Wether it eventually crashes or not is
implementation defined. In any case, anything can happen as per the C
standard. It might apparently continue running normally, (like your
case, which could be because, your library memory manager reserved more
memory as a part of your process, and that they just happen to lie past
your allocated chunk.), or it might misbehave later or dump core
immediately.

It doesn't matter. Once you've created undefined behaviour, anything
might happen.

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-26-2006
santosh wrote:
>
> Your program writes past the end of the array and doing so, invokes
> undefined behaviour. Wether it eventually crashes or not is
> implementation defined. [...]


<pedantry>

It's not even implementation-defined; the implementation
has no obligation to document the consequences. Undefined is
undefined, and there's an end on't.

</pedantry>

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      03-26-2006
Eric Sosman wrote:
> santosh wrote:
> > Your program writes past the end of the array and doing so, invokes
> > undefined behaviour. Wether it eventually crashes or not is
> > implementation defined. [...]

>
> <pedantry>
> It's not even implementation-defined; the implementation
> has no obligation to document the consequences. Undefined is
> undefined, and there's an end on't.
> </pedantry>


Thanks pedantic point duly noted and filed!

 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      03-26-2006
On 26 Mar 2006 10:03:10 -0800, santosh <(E-Mail Removed)> wrote:
> Christian Christmann wrote:

....
>> {
>> char *array;
>>
>> array = (char*)malloc(10 * sizeof(char) );

>
> Don't cast the return value of malloc. A better form of the above
> statement is:
> array = malloc(10 * sizeof *array);
>
> This also has the side effect that if you ever change the base type,
> (char here), you won't have to modify this statement.


Yes; casting malloc()'s return value became obsolete when void * was
introduced, some twenty years ago.

As a side note, typing "sizeof(char)" is pointless, since its value is, by
definition, 1.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.dyndns.org> R'lyeh wgah'nagl fhtagn!
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-26-2006
"santosh" <(E-Mail Removed)> writes:
> Christian Christmann wrote:

[...]
> This also has the side effect that if you ever change the base type,
> (char here), you won't have to modify this statement.
>
>> if ( array == NULL )
>> exit( 0 );

>
> exit(EXIT_SUCCESS); or exit(EXIT_FAILURE) would be more portable though
> zero is always a portable return value to indicate successfull
> termination.


exit(0) is exactly as portable as exit(EXIT_SUCCESS); both are defined
to return a status that indicates successful termination (though not
necessarily the same status).

But since this particular exit() is executed only on a failure of
malloc(), exit(EXIT_FAILURE) would make more sense. (Note that
exit(1), unlike exit(0), is *not* portable.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      03-26-2006
Keith Thompson wrote:
> "santosh" <(E-Mail Removed)> writes:

<snip>
> > exit(EXIT_SUCCESS); or exit(EXIT_FAILURE) would be more portable though
> > zero is always a portable return value to indicate successfull
> > termination.

>
> exit(0) is exactly as portable as exit(EXIT_SUCCESS); both are defined
> to return a status that indicates successful termination (though not
> necessarily the same status).


Err, don't you mean:
"...though not necessarily the same value."
above?

<snip>

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-26-2006
"santosh" <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> "santosh" <(E-Mail Removed)> writes:

> <snip>
>> > exit(EXIT_SUCCESS); or exit(EXIT_FAILURE) would be more portable though
>> > zero is always a portable return value to indicate successfull
>> > termination.

>>
>> exit(0) is exactly as portable as exit(EXIT_SUCCESS); both are defined
>> to return a status that indicates successful termination (though not
>> necessarily the same status).

>
> Err, don't you mean:
> "...though not necessarily the same value."
> above?


No, I meant status. It's also true that it's not necessarily the same
value.

The standard says:

Finally, control is returned to the host environment. If the
value of status is zero or EXIT_SUCCESS, an implementation-defined
form of the status _successful termination_ is returned. If the
value of status is EXIT_FAILURE, an implementation-defined form of
the status _unsuccessful termination_ is returned. Otherwise the
status returned is implementation-defined.

EXIT_SUCCESS, EXIT_FAILURE, and 0 are values of type int that can be
passed to the exit() function. A "status" is a vaguely-defined thing
that's seen by the host environment; it isn't necessarily a value,
particularly an int value, in the sense used within a C program. (The
fact that parameter to exit() is also called "status" is potentially
confusing.)

If EXIT_SUCCESS==0, then presumably both exit(EXIT_SUCCESS) and
exit(0) return the same "status" to the environment. If
EXIT_SUCCESS!=0, then exit(EXIT_SUCCESS) and exit(0) may or may not
return the same "status" to the environment.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      03-26-2006
santosh wrote:
> Christian Christmann wrote:


<snip>

>> if ( array == NULL )
>> exit( 0 );

>
> exit(EXIT_SUCCESS); or exit(EXIT_FAILURE) would be more portable though
> zero is always a portable return value to indicate successfull
> termination.


<snip>

As well as the comments others have made, exit(EXIT_SUCCESS) and
exit(EXIT_FAILURE) are no more portable than exit(0) since all three are
completely portable. Any other value and zero and I would have agreed.
However, in this case exit(EXIT_FAILURE) would have been far better
style since the program has failed.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
 
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
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
why am I getting a segmentation fault? Jay donnell Python 6 01-22-2005 04:34 AM
Segmentation Fault in fclose()...why? VB C++ 3 01-15-2005 04:26 PM
Why segmentation fault in this simple code? Polar C Programming 11 08-09-2004 07:26 PM
Why segmentation fault Anks C Programming 3 09-14-2003 12:05 PM



Advertisments