Why is the output 0?!?!

This is a discussion on Why is the output 0?!?! within the C Programming forums, part of the General Programming Boards category; Code: #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { int i = 1; char buf[4]; strcpy(buf, "AAAA"); printf("%d\n", ...

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    3

    Why is the output 0?!?!

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

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Probably because you allocated 4 bytes for buff but wrote 5 bytes with the strcpy(). The 5th byte very likely over wrote part of the memory that i uses.

  3. #3
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    Indeed. Don't forget that strings in C have a null character assumed at the end.

  4. #4
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        int i = 1;
        char buf[4];
    
        strcpy(buf, "AAA\0");
        printf("%i\n", i);
    
        return 0;
    }

  5. #5
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    Kleid-0 - the null character is assumed.

  6. #6
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    And infact your string literal still assigns 5 bytes.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    3
    YAArrrrr... I should have known. Thanks guys.

    But when declaring variables, is the memory always assigned in contiguous blocks? Any links to more info on these kinds of details?

  8. #8
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,333
    > is the memory always assigned in contiguous blocks?
    Whether i is before or after buf in memory is implementation specific.
    How much space is between variables in memory is also implementation specific.

    Correct code should rely on neither of these.
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    3
    > Correct code should rely on neither of these.

    Yeah, I am aware of this. I just wanted to know more about how exactly memory is allocated when declaring variables in C.

    Ofcourse its not a good idea to use unallocated space.

  10. #10
    Registered User Scribbler's Avatar
    Join Date
    Sep 2004
    Location
    Aurora CO
    Posts
    266
    Compilers may make a difference, but the OS is also a major factor.

    Typically (I took this example from windows), you'll see that memory is organized similar to this...

    -Storage (uninitialized) variables <---- High Address
    -Static Variables
    -Read Only
    -Constants (not user accessible)
    -Code (program instructions)
    -Heap
    -Stack
    -OS reserved <---- Low Address.

    So for example, if you take your original code (with the error) and initialize variable i as static...
    Code:
    static int i = 1;
    you'll find that you receive the output you were looking for (obviously there is still an error in the program, just not as apparent).
    Last edited by Scribbler; 01-16-2005 at 02:08 PM.

  11. #11
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    Compilers may make a difference, but the OS is also a major factor.
    I believe OS is included in "implementation" - but that's good information
    Last edited by sean; 01-16-2005 at 05:05 PM.

  12. #12
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Quote Originally Posted by sean_mackrory
    Kleid-0 - the null character is assumed.
    dangit! Well at least the output was not 0!

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Quote Originally Posted by Thantos
    And infact your string literal still assigns 5 bytes.
    Does it?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Quote Originally Posted by Dave_Sinkula
    Does it?
    Bah you're right it would stop at the first null character Shows you how often I use strcpy now that I'm using C++ almost full time

  15. #15
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,246
    Yeah, I am aware of this. I just wanted to know more about how exactly memory is allocated when declaring variables in C.
    This question cannot be directly answered since memory is not allocated by C, it is allocated by the OS. That said, I can explain how the memory most likely was allocated on your system to give you the results you got.

    Code:
        int i = 1;
        char buf[4];
    In your code, the above declarations are the ones that are requesting memory. You are requesting space for 1 integer, and 4 chars. On 99% of the computers in use today, integers are 4 bytes, and characters are 1 byte each. Keep in mind though that these memory sizes are not standard at all. An integer could be 8 bytes on some machines (new 64 bit processers for instance), and a char could be 2 bytes or some other values.

    The memory allocated in your program is allocated on what's called the stack. First the 4 bytes for the integer are pushed onto the stack, then the 4 bytes for the char array. Here is a small diagram:
    Code:
    Top of stack on left, bottom of stack on right:
    [ ][ ][ ][ ][ ][ ][ ][ ]
    |  chars    | integer  |
    Now first, i is assigned the value of 1. Now our stack looks like:
    Code:
    Top of stack on left, bottom of stack on right:
    [ ][ ][ ][ ][1][0][0][0]
    |  chars    | integer  |
    Now you may ask yourself why is the number 1 stored as 0x1000 instead of 0x0001? The answer is that many processers store data in little endian format. This means that the least significant byte goes first.

    Next you perform:
    Code:
    strcpy(buf, "AAAA");
    Keep in mind strcpy automatically places a trailing null terminator at the end of the string. Now your stack looks like (assuming ASCII character set):
    Code:
    Top of stack on left, bottom of stack on right:
    [41][41][41][41][0][0][0][0]
    |    chars      | integer  |
    Notice the trailing null terminator overwrote the least significant byte of your integer.

    This explains a little bit about what goes on "under the hood". It doesn't actually have much to do with the C programming language, but I think it's good stuff to know

Page 1 of 3 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. code output...
    By roaan in forum C Programming
    Replies: 6
    Last Post: 07-03-2009, 02:22 AM
  2. Help for my output array
    By qwertysingh in forum C Programming
    Replies: 1
    Last Post: 02-17-2009, 02:08 PM
  3. Replies: 4
    Last Post: 11-30-2005, 03:44 PM
  4. Formatting output into even columns?
    By Uncle Rico in forum C Programming
    Replies: 2
    Last Post: 08-16-2005, 05:10 PM
  5. Output problems with structures
    By Gkitty in forum C Programming
    Replies: 1
    Last Post: 12-16-2002, 04:27 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21