Thread: Array Lengths

  1. #1
    Registered User SCRIPT_KITTEH's Avatar
    Join Date
    Apr 2013
    Posts
    74

    Red face Array Lengths

    Hi all,

    Been quite some time since I've posted here or practiced C for that matter, but recently starting to get back into it.

    I was reading in a book I had about C that an array has at the very end a "null character" signifying the end of the string inside it, "/o". So that made me think, "I guess one needs to declare arrays as having 1 extra space than one expects the array to need. I wonder what will happen if I exceed the array length?"

    So I made a program to test it out. Here is the program/results:

    Code:
    #include <stdio.h>
    
    int main(void){
    
    
            char name[3];
    
    
            printf("\nWhat's your name?\n");
            scanf("%s", name);
    
    
            printf("\nHi, %s.\n", name);
    
    
            return 0;
    }
    results:

    http://i.imgur.com/wHlYUVq.png

    As you can see my name was able to fit in the array somehow even though I only allocated 3 bytes to the array. I tried again using my legal first name, Benjamin, and it was still able to fit.

    What exactly is going on here? How is the array able to hold my name when I declared it as only having 3 bytes?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,850
    Quote Originally Posted by SCRIPT_KITTEH
    I wonder what will happen if I exceed the array length?
    You are in the realm of undefined behaviour. It so happens that it "works" for you with the input that you tested with, but say, if you enter longer input, or if your program was more complex, or if you compile it on a different system, with a different compiler, or with different compiler flags, you might get some kind of error.

    For example, I enter all the letters of the English alphabet, in lowercase, as the "name", and your program crashed for me. Or, I changed your program to:
    Code:
    #include <stdio.h>
     
    int main(void) {
        char greeting[] = "Hi";
        char name[3];
    
        printf("\nWhat's your name?\n");
        scanf("%s", name);
    
        printf("\n%s, %s.\n", greeting, name);
    
        return 0;
    }
    Then entered "Benjamin", and got this output:
    Code:
    jamin, Benjamin.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    In general, exceeding the bounds of an array is undefined behavior. In your case, in this instance, everything worked OK, but for me?
    Code:
    Child process PID: 4480
    Program received signal SIGSEGV, Segmentation fault.
    So I typed a bigger name to induce the error, but your code makes that possible, so it's fair, right?

    Code:
    char name[4];
    scanf ("%3s", name);
    Now it is a degree safer.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    1) An array does not have to have a "null character" at the end. Arrays have two properties: the type of the elements, and the length. So "int x[3];" specifies that x as an array of three ints.

    2) By convention, a string literal (such as "Hello") is represented in the form of an array of char, with a zero sentinel at the end. So "Hello" is represented as an array of 6 chars, with values 'H', 'e', l', 'l', 'o', and zero. A character with value zero is also equivalent to '\0' (the \xxx as a char constant treats xxx as a hex value). All functions in C that work with strings (strcpy(), strcmp(), strlen(), etc etc) adhere to this convention (for example, strlen() keeps counting characters until it finds one with value zero). A convention is not a law of nature.

    3) This convention is specific to arrays of chars and strings. It is not applicable to other types. So an array of int is not guaranteed to have a zero at the end.

    4) When the length of any array is exceeded - i.e. an element is accessed outside array bounds - the result is simply undefined behaviour according to the standard. If writing past the end of an array, the result is writing to memory (which might not even exist) that doesn't belong to an array. The consequences of that are undefined (anything is allowed to happen). "Anything" is pretty far reaching. It can include the code appearing to behave sensibly. It can include writing garbage. It can include reformatting your hard drive. Whatever happens, the behaviour is correct - and the compiler is not required to emit a diagnostic. It is the code that exhibits undefined behaviour which is incorrect.

    5) It might look to you that you were able to fit more than three characters into a three-character array. That is an incorrect observation. What is actually happening is that there is some memory allocated after the array that is being overwritten by the scanf() call. That memory is not even guaranteed to exist as far as the program is concerned. A host operating system might detect that behaviour and terminate your program. The code might overwrite some other memory used by your program (for example, allocated to variables in other functions). The result is completely unpredictable. If the program has not been forceably terminated during the call of scanf(), the printf() call simply starts printing each character in the array name, and attempts to keep going until it finds a character with value zero. Again, the behaviour is completely unpredictable.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Feb 2014
    Posts
    1
    here name is a pointer, if u enter characters more than 3, it will accept and print while null not found, but it is not good because allocated memory is 3 bytes and after 3 bytes can be used after, so keep in mind to allocate memory string length +1, if u run this code in gcc or updated compiler, this will produce an error.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,114
    > here name is a pointer,
    An array name is not a pointer.
    Arrays and Pointers
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Quote Originally Posted by grumpy View Post
    2) By convention, a string literal (such as "Hello") is represented in the form of an array of char, with a zero sentinel at the end. So "Hello" is represented as an array of 6 chars, with values 'H', 'e', l', 'l', 'o', and zero. A character with value zero is also equivalent to '\0' (the \xxx as a char constant treats xxx as a hex value). All functions in C that work with strings (strcpy(), strcmp(), strlen(), etc etc) adhere to this convention (for example, strlen() keeps counting characters until it finds one with value zero). A convention is not a law of nature.
    Slight correction: it's treated as an octal value.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Slight correction: it's treated as an octal value.
    O_o

    You "corrected" it from being right to being wrong.

    You can use '\nnn' for octal, but '\xxx' is hexadecimal.

    The 'x' makes all the difference.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    For clarity: for hexadecimal constants, the first 'x' after the \ is a literal x (i.e. the 24th letter of the English alphabet). The next two are hexadecimal digits. In the case of the octal escape sequence, they are simply all octal digits following a \, no letters.

    For reference, see 6.4.4.4 of C99/C11 standards.

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    clarity
    O_o

    My cranial parasites tell me I could not possibly have been clearer.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    Quote Originally Posted by phantomotap View Post
    O_o

    My cranial parasites tell me I could not possibly have been clearer.

    Soma
    The \xxx form was in grumpy's post too, it's not just your post. Using the same symbol for both a literal 'x' and a hexadecimal digit seems to leave room for confusion. This is, I suspect, part of nonoob's confusion -- he (she?) thought that all three x's were supposed to be the same type of thing, which would only make sense if grumpy meant them to be octal digits. How is one supposed to know that the first x in \xxx is a literal 'x' while the next two are in fact hexadecimal digits 0-9, a-f or A-F? Which of those 3 x's "makes all the difference". This is exacerbated by the use of \nnn for octal, where all three n's are octal digits -- but if somebody already knows the hex version, but not the octal, they may read your post and think that an octal constant starts with a backslash, then a literal 'n', then two octal digits.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    ^_^

    Yes. I appreciate the likely confusion.

    My comment was a joke and a reference to: Maggots - Limbo Wiki from near "news" Middle school warns snorting Smarties may lead to nasal maggots - CBS News

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  13. #13
    Registered User SCRIPT_KITTEH's Avatar
    Join Date
    Apr 2013
    Posts
    74
    Hi all, for some reason I thought it would email me when this topic received replies, but it didn't, so I just now saw the replies & wanted to say thanks!

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by phantomotap View Post
    Yes. I appreciate the likely confusion.
    As do I, the one who caused excessive likelihood of confusion in this case through quick typing (my fingers didn't faithfully capture what I intended).

    nonoob was right in spotting my mistake, as were subsequent posts pointing out he made a slight error too.

    To be clear (and recap the corrections, and corrections of corrections ....) an octal character value is in the form of \nnn where each n indicates an octal (base 8) digit. So '\0' (equivalent to '\000' is a character with value zero, '\10' is a character with value 8. Similarly, a hex constant is indicated by the escape sequence \xhh where x is the letter x, and the h's represent hexadecimal (base 16) digits. So '\xE0' is a character with value 0xE0 (with decimal value 224 = 14*16).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Restricting Character lengths
    By collude in forum C Programming
    Replies: 7
    Last Post: 04-06-2011, 10:17 PM
  2. Problem with lengths
    By Borowsky in forum C Programming
    Replies: 0
    Last Post: 10-02-2010, 03:57 PM
  3. failing with certain string lengths
    By Bleech in forum C Programming
    Replies: 7
    Last Post: 06-01-2007, 03:36 PM
  4. Replies: 4
    Last Post: 04-04-2003, 12:35 PM
  5. constant char lengths are getting me down
    By bennyandthejets in forum C Programming
    Replies: 1
    Last Post: 07-20-2002, 07:26 AM