ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I need to declare a variable that is not in the stack memory but in the heap, like below
Code:
struct mystruct *name;
Should I declare it outside all functions (even outside main()) at the begin of file?
Heap memory is used when you use malloc as in
Code:
name = malloc(sizeof(struct mystruct));
if you don't wan't a variable to be on the stack then you could preface its declaration with static but then the same variable will used everytime the function is run so recursion might not be practicable.
Declaring variables outside of any function will make them global and they should not be created on the stack (but I'm not sure if that is a rule).
In your two examples, r exists on the stack in the first example and globally in the second. Note that you have not initialized r (with malloc) yet so the value of r (and therefore what it points to) is indeterminate.
> I just made two examples:
> I use MAC OS X and the output is the same:
> that is NULL.
That's cool. Only remember that the first one isn't guaranteed to be always NULL; actually, it is memory-garbage that happened to be NULL in this example.
Any variable that is declared within the body of a function is "local" to that function. It exists only when the function-instance does [i](recursive functions have a copy for each instance), and its lexicalscope is such that only code within the body of the function can "see it" to refer to it.
Any variable that is declared outside the scope of all functions is global and can be accessed by any function.
The "C" language does not provide for variable-initializers. You should assume that the value of all variables is "unpredictable."
static and global variables are initialised to null in C.
Yes.
Exception being if the linker has a manipulated map file, and/or the process initializer code is customized not to initialize globals. Which really only happens in embedded programming.
It is a good rule to always initialize variables to a known state. global/static or local.
About memory returned by malloc. A decent desktop OS will always wipe that memory before given to the process asking for memory. Therefore it will very often be wiped to zero.
BUT. If a process first malloc a block of memory, and then frees the same block, and then after that mallocs another block of the same size - Chances are that the process hasn't yet released that block of memory to the system garbage collection. So the newly malloced block of memory could still have the contents retained from the previous malloc.
In the VMS operating system the system manager can on the fly set how memory pages are wiped or not. It can be set to any combination of: Wipe at allocation, or not. Wipe when freed, or not. and cyclic scrubbing of available memory, (or no scrubbing), when returning "dirty pages" to be free pages available for allocation.
So the rule is: Always initialize variables and allocated memory.
Example of clearing a struct bios_geometry_t of potentially undefined size, pointed to by the first member '0' of the array 'fr' of struct, specifically it's struct member 'BiosGeom':
When a program starts, a certain portion of the data-segment is allocated for "statically-allocated, 'global,' variables," which includes all variables that are declared outside of any function. All such variables are each bound to one, unchanging memory-address within this space.
Another area of memory, usually referenced by a separate processor "stack segment" register, is used to handle subroutine calls. Any memory needed by an executing subroutine/function for its "local" variables is only needed while that particular function-call instance exists, after which it can be re-used, therefore a "push-down stack" paradigm is used to manage it. (This also supports recursion, in which a subroutine/function can safely call itself, without conflict.) The stack area grows and possibly shrinks as required.
The third and final area of memory ... unrelated to the other two ... is called "the heap." This space is used to satisfy requests for memory that are made ad hoc by the running program itself. (The term, "heap," is meant to represent the fact that this memory area has no pre-determined structure or organization of its own.) When a program determines that it needs some amount of memory, it asks for it (malloc()), and, when it decides that it no longer needs some piece, it returns it (free()).
Since it is, of course, impossible to know just where the requested memory-block (in "the heap") might be, pointers are always used to refer to these areas ... indirectly.
A pointer, physically speaking, is merely an integer value of some certain width whose contents are understood to represent a memory-address. ("Zero" has the special meaning, NULL.) The term refers to the fact that, while the particular (integer ...) value of the pointer is uninteresting, the data at that location ("what the pointer 'points to' ...") is.
Pointers, being "merely high-falutin' integers," can be stored anywhere: in the BSS area, in a stack ("local") variable, or in the case of so-called "linked lists" and other "data structures," elsewhere in the heap.
I need to declare a variable that is not in the stack memory but in the heap, ...
Should I declare it outside all functions (even outside main()) at the begin of file?
Reviewing the initial question, i give the following "short" answer:
Either declare the variable globally, outside all functions. Or declare the variable inside a function, but use a 'static' declaration, which will give the variable the same allocation as for the global variables, with the exception that the variable is only visible inside that function.
Being a static variable makes it allocated such that its contents are preserved between different serial invocations of the function. Best practice is still to reinitialize the variable everytime the function is invoked, and not use the side effect of the static variable preserving its content. (The exception being the static members of an object/class instantiation in C++).
Use global static variables to preserve data between function invocations. Not the function local static variables.
Please be aware that a static declared variable in a function will make that function non-reentrant, and that function may not be used in multithreaded applications without a locking mechanism preventing simultaneous execuion of the non-reentrant function. Also note that such a static variable can be pointed to by a function returning a pointer to the contents, and that another invocation of that function will overwrite the contents of the pointed out return data. Thus, non-reentrant.
Another concept that provides a form of static allocation that can be reentrant is the use of "workspaces" allocated in some form of block pool handler. Simplest implementation of this may well be allocation of "new objects of a class" in C++, each getting it's own separate workspace allocated in heap when instantiated, and as such capable of running multithreaded in the form of "one object per thread". But the functions of such an object are still not reentrant.
For realtime performance, and also for reliable execution, the concept of avoiding dynamic allocation is essential. Global and static allocation is enforced, and dynamic allocation kept to an absolute minimum.
Having lots of small functions that allocate large arrays/buffers dynamically, for a short time, either on stack or in paged memory, are detrimental to reliable, predictable realtime performance.
I guess the OP wanted to know whether definition a pointer also defines an object of the pointed type [no], and where that object will reside [nowhere].
And, whenever possible, I now strongly recommend that people write "new stuff" in a higher-level language, even "C++," which does possess built-in support for "real strings," container classes that "just work," and so-forth. You're leveraging a much more expressive source-code language that already knows how to "do the right thing for you" in many useful cases.
The "C" language is, in a very real sense, just a very small step-up from assembly language ... and-d-d-d, it was designed so to be! But, when you write code in it, you're obliged to concern yourself, all over again, with a bunch of niggling things that ought not have to concern you. You're opening yourself up to "more ways that you can possibly screw-up" than you need to. (Given that you are, of course, "going to screw up," make the screw-ups interesting, not mundane.)
Use global static variables to preserve data between function invocations. Not the function local static variables.
Better still, any variables that need to be conserved between function invocations should be stored by the calling function and a pointer passed to those functions that need it. The use of global variables is generally not good programming practice because of portability issues and the difficult to find bugs it can cause.
Quote:
Originally Posted by wroom
Please be aware that a static declared variable in a function will make that function non-reentrant,
... but not necessarily non-recursive. As long as the value of the static variable prior to the latest invocation of the function can be computed, recursion is still possible. (In my BASIC programming days, this was the method I used as an alternative to setting up data stacks for recursive subroutining). I agree that there are usually better alternatives to local static variables (other than in main()). Of course, if re-entrancy is not an issue then the point is moot.
Quote:
Originally Posted by wroom
For realtime performance, and also for reliable execution, the concept of avoiding dynamic allocation is essential. Global and static allocation is enforced, and dynamic allocation kept to an absolute minimum.
Having lots of small functions that allocate large arrays/buffers dynamically, for a short time, either on stack or in paged memory, are detrimental to reliable, predictable realtime performance.
I have never heard of this rule of thumb before. Is this because of the way Linux allocates memory? There are many cases where the amount of memory required can not be known beforehand and dynamic allocation is the only way around this. In some languages (like Java), every non-elemental variable has to be dynamically allocated.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.