LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-04-2015, 06:32 AM   #1
savio
LQ Newbie
 
Registered: May 2015
Posts: 29

Rep: Reputation: Disabled
global declaration is in stack or in heap?


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?
 
Old 11-04-2015, 06:56 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
If you put this line into a function, it will be an uninitalized pointer, that exists on the stack.

If you put this line outside any function, it will be an NULL-initalized pointer, a global variable (neither heap or stack)
 
Old 11-04-2015, 07:54 AM   #3
savio
LQ Newbie
 
Registered: May 2015
Posts: 29

Original Poster
Rep: Reputation: Disabled
I just made two examples:

Code:
#include <stdio.h>

struct record {
  int elem;
  char c;
} myrecord;

int main(int argc, char** argv) {

  struct myrecord *r;

  printf("myrecord *r = %p\n", r);

  return 0;

}
and

Code:
#include <stdio.h>

struct record {
  int elem;
  char c;
} myrecord;

struct myrecord *r;

int main(int argc, char** argv) {

  printf("myrecord *r = %p\n", r);

  return 0;

}
I use MAC OS X and the output is the same:

Code:
myrecord *r = 0x0
that is NULL.
 
Old 11-04-2015, 08:36 AM   #4
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by savio View Post
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.

Last edited by psionl0; 11-04-2015 at 08:37 AM.
 
Old 11-04-2015, 08:54 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
> 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.
 
Old 11-04-2015, 11:25 AM   #6
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,663
Blog Entries: 4

Rep: Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944
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 lexical scope 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."
 
1 members found this post helpful.
Old 11-06-2015, 02:37 AM   #7
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
static and global variables are initialised to null in C.
 
Old 11-06-2015, 12:36 PM   #8
wroom
Member
 
Registered: Dec 2009
Location: Sweden
Posts: 159

Rep: Reputation: 31
Quote:
Originally Posted by bigearsbilly View Post
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':
Code:
memset(&(fr[0].BiosGeom),0,sizeof(struct bios_geometry_t));
Or the simpler example to allocate an array of 99 unsigned elements, all initialized to 0:
Code:
unsigned * x;
x = malloc(sizeof(unsigned)*99);
if (x == 0) abort();
memset(x,0,sizeof(unsigned)*99);
 
Old 11-06-2015, 01:08 PM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Or, two more options:
Code:
uptr = calloc (sizeof (unsigned), 99);
uptr = calloc (sizeof *uptr, 99);
 
Old 11-06-2015, 07:29 PM   #10
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,663
Blog Entries: 4

Rep: Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944
Upon re-reading, I realize that I slightly-misspoke.

There are three memory areas that a program can use:
  1. the "BSS" area ...
  2. The "stack." And ...
  3. The "heap."

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.
 
Old 11-06-2015, 09:02 PM   #11
wroom
Member
 
Registered: Dec 2009
Location: Sweden
Posts: 159

Rep: Reputation: 31
Quote:
Originally Posted by savio View Post
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.
 
Old 11-06-2015, 11:34 PM   #12
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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].
 
Old 11-07-2015, 09:50 AM   #13
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,663
Blog Entries: 4

Rep: Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944Reputation: 3944
Probably.

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.)
 
Old 11-07-2015, 12:15 PM   #14
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,868
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Yes, C++ is very good for beginners. Details here: http://yosefk.com/c++fqa/
 
Old 11-08-2015, 02:07 AM   #15
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by wroom View Post
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 View Post
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 View Post
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
stack faster than heap? eep6sa1@ucy.ac.cy Programming 24 12-13-2008 03:32 AM
How to set Stack/Heap Limit ? gloridel Linux - Kernel 1 06-11-2007 02:56 AM
heap or stack yashwantpinge Programming 1 03-17-2006 07:25 AM
C Global Declaration Aju Programming 3 09-29-2005 04:21 AM
Perl global declaration? mikeshn Programming 1 08-16-2002 06:10 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:21 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration