Thread: Are C arrays stored in the stack or the heap?

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    21

    Lightbulb Solved: Are C arrays stored in the stack or the heap?

    Edit, for those looking for a quick Answer: All variables and arrays are stored in the stack, unless: Malloc is used, the variable is static, the variable is global.
    The code below is not supposed to work, "10" was printed by chance, a different compiler could have thrown an error or print something different.
    Many websites say that C arrays are stored in the Stack, unless malloc() is used. If that is true, then an array is supposed to be destroyed after a function ends. However, I ran a test that contradicts this:
    Code:
    int* testfunc()
    {
        int x[10];
        x[0]=10;
        return x;
    }
    
    
    int main()
    {
        int *x=testfunc();
        printf("%i",*x);
    }
    The output is "10", In other words, the array X was not destroyed and the main() function has managed to access the array. Can someone explain what is going on?
    Last edited by butteflymentor; 03-10-2012 at 07:48 AM. Reason: Solved

  2. #2
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Is it possible that the function "testfunc()" is returning a COPY of the array "x" ? Edit: The answer is no.
    Last edited by butteflymentor; 03-10-2012 at 07:53 AM.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by butteflymentor
    The output is "10", In other words, the array X was not destroyed and the main() function has managed to access the array. Can someone explain what is going on?
    Suppose the array x was destroyed. What output did you expect? 0? 0xdeadbeef?

    Basically, you are observing the result of undefined behaviour. It so happens that the output is 10, probably because the memory was left unchanged. The output could have been something else, or the compiler could have rejected your program, or the compiler could have generated code to print "hello world!", etc. Don't do this.
    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

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    21

    Lightbulb

    Suppose the array x was destroyed. What output did you expect? 0? 0xdeadbeef?
    I was expecting the compiler to throw an error or something.
    This time, I ran this modified code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    
    int* testfunc()
    {
        int x[10];
        x[0]=10;
        return x;
    }
    void testfunc2()
    {
        int t[10];
        t[0]=4;
        return ;
    }
    int main()
    {
        int *x=testfunc();
        testfunc2();
        printf("%i",*x);
    }
    And the output was ...*drum rolls*.... 4!
    It seems that this is indeed the result of undefined behavior. I assume that a function's local variables remain in the stack until they are overridden by another function call (please correct me if i'm wrong).

    Thank you very much for your assistance

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by butteflymentor
    I assume that a function's local variables remain in the stack until they are overridden by another function call (please correct me if i'm wrong).
    Conceptually, no. The thing is, the memory that they occupied remains.
    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

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Conceptually, no. The thing is, the memory that they occupied remains.
    Is my assumption incorrect? I don't see how "a function's local variables remain in the stack" differs from "the memory that they occupied remains".
    Last edited by butteflymentor; 03-10-2012 at 07:39 AM.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > I was expecting the compiler to throw an error or something.
    You mean like this?
    Code:
    $ gcc -W -Wall -Wextra bar.c
    bar.c: In function ‘testfunc’:
    bar.c:11: warning: function returns address of local variable
    bar.c: In function ‘main’:
    bar.c:24: warning: control reaches end of non-void function
    But a compiler can't detect every mistake.
    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.

  8. #8
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Exactly! what compiler did you use? The compiler I am using (mingw) does not detect this error.

    EDIT: that was a silly question. The first line says "Gcc"
    Last edited by butteflymentor; 03-10-2012 at 07:47 AM.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by butteflymentor
    I don't see how "a function's local variables remain in the stack" differs from "the memory that they occupied remains".
    Conceptually, the local variables don't exist once the function returns. They are gone. But just as your computer is (hopefully) not destroyed whenever you shut it down, the memory that was in use for those variables is still around.

    Quote Originally Posted by butteflymentor
    The compiler I am using (mingw) does not detect this error.
    Increase your warning level.
    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

  10. #10
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Quote Originally Posted by laserlight View Post
    Increase your warning level.
    Any idea how to achieve that in Code::blocks?
    I checked all boxes in: Settings > Compiler And Debugger > Compiler Settings > Compiler Flags > Categories:Warnings. Yet the error is still not being detected.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by butteflymentor
    Any idea how to achieve that in Code::blocks?
    I checked all boxes in: Settings > Compiler And Debugger > Compiler Settings > Compiler Flags > Categories:Warnings. Yet the error is still not being detected.
    Err... weirdly enough, I find that the MinGW port of gcc 3.4.5 complains even at the default warning level. Which version of the MinGW port of gcc are you using with Code::Blocks?
    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

  12. #12
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Quote Originally Posted by laserlight View Post
    Which version of the MinGW port of gcc are you using with Code::Blocks?
    I am not sure. I downloaded the Code::Blocks version which includes a read-to-use Mingw. Oddly, it does not state which version of Mingw is included.
    The Readme says: "4.4.1-tdm-2"... I am not sure whether this is the version number or not.

  13. #13
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by butteflymentor View Post
    Many websites say that C arrays are stored in the Stack ...
    There is no requirement that non-static function variables be implemented on a stack. Yes, this is the easiest way to implement them so almost all implementations use a stack. However, there are implementations that do not use a hardware stack. I never investigated the only one that I actually heard of, but apparently the microcontroller may not have had a generalized stack. That compiler may or may not have been standards compliant. [For example, I am not sure if it supported recursive functions.]

    Quote Originally Posted by laserlight View Post
    Basically, you are observing the result of undefined behaviour.
    Quote Originally Posted by butteflymentor View Post
    I was expecting the compiler to throw an error or something.
    Undefined behavior means the behavior is not specified the language standard. There are some other undefined behaviors (as far as the standard is concerned) that allow one to do some good things. But at that point, one is depending on something that may not work with another compiler or a different microprocessor or microcontroller family. I would not like my compiler to "throw an error" for these situations.

    And this is why the messages being discussed later in the thread for this particular example are warnings not errors. Some programs may have been written to live with the behavior that you are observing. Yes, those programs are "fragile" but they sometimes have their uses.

    Also, C was designed to minimize the "required" run-time checking and thus trust the programmer. This was intended to maximize run-time performance during the early implementations. To catch some kinds of undefined behaviors, the run-time performance would be significantly affected. ["Existing compilers provide no run-time checking of array subscripts, argument types, etc." Introduction to K&R 1st Ed. 1978. "Nevertheless, C retains the basic philosophy that programmers know what they are doing; ..." Introduction to K&R 2nd Ed. 1988.].

    Quote Originally Posted by butteflymentor View Post
    I assume that a function's local variables remain in the stack until they are overridden by another function call (please correct me if i'm wrong).
    Yes, in most of the implementations that I have used. But one could write a compiler and run-time environment at every function return would over-write the non-static function variables with some value. There would be a run-time performance penalty that might or might not be significant in current environments.

  14. #14
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by butteflymentor View Post
    I was expecting the compiler to throw an error or something.
    The compiler only checks the syntax, not the semantics. Run your code through lint in order to spot this kind of mistake.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by pheininger
    Undefined behavior means the behavior is not specified the language standard.
    I would avoid the phrase "not specified" to describe undefined behaviour because "unspecified behaviour" really refers to a case where there are a few possibilities for the behaviour specified, but which exactly is to be chosen by a language/standard library implementation is unspecified by the standard.

    Quote Originally Posted by pheininger
    There are some other undefined behaviors (as far as the standard is concerned) that allow one to do some good things. But at that point, one is depending on something that may not work with another compiler or a different microprocessor or microcontroller family. I would not like my compiler to "throw an error" for these situations.

    And this is why the messages being discussed later in the thread for this particular example are warnings not errors. Some programs may have been written to live with the behavior that you are observing. Yes, those programs are "fragile" but they sometimes have their uses.
    You're thinking of implementation defined behaviour, not undefined behaviour. An implementation is free to make those warnings concerning undefined behaviour be errors, or generate whatever code it likes.
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. are methods stored in the heap or the stack?
    By y99q in forum C# Programming
    Replies: 2
    Last Post: 01-30-2012, 03:02 PM
  2. Stack or Heap ?
    By Stuart Dickson in forum C Programming
    Replies: 4
    Last Post: 05-06-2010, 12:40 PM
  3. Should I use the Heap or the Stack?
    By Swerve in forum C++ Programming
    Replies: 2
    Last Post: 10-08-2009, 12:38 PM
  4. heap or stack?
    By sawer in forum C++ Programming
    Replies: 4
    Last Post: 01-24-2006, 02:36 AM
  5. Stack and Heap
    By Barjor in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 01-29-2002, 09:11 AM