0

Possible Duplicate:
Why don’t i get “Segmentation Fault”?

Why does this code work? If the first element only hold the first characer, then where are the rest of characters being stored? And if this is possible, why aren't we using this method?

Notice line 11: static char c[1]. Using one element, you can store as much characters as you want. I use static to keep the memory location alive outside of the function when pointing to it later.

#include <stdio.h>

void PutString( const char* pChar ){
   for( ; *pChar != 0; pChar++ )
   {
      putchar( *pChar );
   }
}

char* GetString(){
    static char c[1];
    int i = 0;
    do
    {
        c[i] = getchar();
    }while( c[i++] != '\n' );
    c[i] = '\0';
    return c;
}

void main(){
    PutString( "Enter some text: " );
    char* pChar = GetString();
    PutString( "You typed the following:\n" );
    PutString( pChar );
}
Community
  • 1
  • 1
adabo
  • 87
  • 7
  • 4
    It's undefined behaviour. Anything goes, but all bets are off. (`void main` is rather odd too) – Flexo Nov 04 '12 at 20:09
  • 1
    And about 10,000 others. – Ed S. Nov 04 '12 at 20:11
  • In other words, the memory could be accessed by the program because it thinks it's not being used? – adabo Nov 04 '12 at 20:11
  • @EdS., ahh ok. I didn't know the right keywords to type for searching. I was afraid I might be asking something already asked. – adabo Nov 04 '12 at 20:13
  • @Flexo, what is the odd part of void main? – adabo Nov 04 '12 at 20:17
  • @adabo: It's fine, not an easy thing to search for if you don't know what is going on and, if you do, you don't need to search for it :). I suggest a quick read of the language specification which explains all of this. – Ed S. Nov 04 '12 at 20:19
  • 1
    @adabo: `main` should return `int`. – GManNickG Nov 04 '12 at 21:00

5 Answers5

2

C doesn't check for array boundaries, so no error is thrown. However, characters after the first one will be stored in memory not allocated by the program. If the string is short, this may work, but a long enough string will corrupt enough memory to crash the process.

Diego
  • 18,035
  • 5
  • 62
  • 66
2

You can write wherever you want:

char *bad = 0xABCDEF00;
bad[0] = 'A';

But you shouldn't. Who knows what the above lines of code will do? In the very best case, your program will crash. In the worst case, you've corrupted memory and won't find out until much later. (And good luck tracking down the source!)

To answer your specific questions, it doesn't "work". The rest of the characters are stored directly after the array.

moswald
  • 11,491
  • 7
  • 52
  • 78
  • It makes sense that it's not working. Because it's actually not adding new elements. It's writing to undefined memory. Good point. – adabo Nov 04 '12 at 20:26
1

You are just very (un)lucky, that you are not overwriting some other data structures. The array definitely cannot store as much characters as you want - sooner or later you either silently corrupt your memory (in the worse case), or hit a segfault by accesing a memory your process hasn't mapped. The fact that it works is likely because the compiler didn't place any other data after your c[1]. Just try to add a second array, let's say static char d[1]; after c, and then try reading from it - you'll see the second character from c.

peterph
  • 980
  • 6
  • 11
1

C++ does not do bounds checking on arrays. That's for performance reasons; checking every array index to see if it's outside the bounds would incur an unacceptable runtime overhead. Avoiding overhead has always been a design goal of C++.

If you want bounds checking, you should use std::vector instead, which does provides it as an optional feature through std::vector::at().

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
1

In this case the behavior is undefined: according to the compiler / the current state of the memory / ..., it may seems to run fine, it may write corrupted chars, or it may crash because of a sefault.

Linking against Electric Fence or running in valgrind may help to find such errors at runtime.

gturri
  • 13,807
  • 9
  • 40
  • 57