Using static instead of malloc - C-language - c

In my window app made in c (using gtk) I first had to make a pointer to pointer that I sent to a callbackfunction.
Since i sent the pointer to another function I thought I had to allocate memory on the heap for it that is:
GtkWidget **entry;
entry = malloc(5 * sizeof(GtkWidget));
entry[0] = entry_a;
entry[1] = entry_s;
entry[2] = entry_t;
entry[3] = entry_v;
entry[4] = entry_r;
the GtkWidget variable is a local variable
But someone told my that this is not neccessary since it could be declared as static instead
static GtkWidget *entry[5];
correct - the program works using a static GtkVidget-pointer instead. My question is why and what does this static mean in this context?

All variables with a static storage class will have a program execution lifetime and internal linkage; its scope, however, depends on where it is declared.
To address the question you asked, whether to use a static array or mallocing an array is really something that must determined on a case by case basis. For the most part, however, memory is cheap, so you shouldn't have to worry about performance issues one way or the other, unless your array size becomes excessive (an int array size of 5 is rather insignificant). Protecting the integrity of an array is much more of a concern. That is why, as a rule of thumb, you should make a variable's scope as small as possible.

They do different things.
If you allocate an array (or any object) using malloc, that memory is allocated at run time when malloc is called, and it continue to exist until free it (i.e., pass the pointer value returned by malloc to the free function). (realloc can also deallocate malloced space, but that's not relevant here.)
If you define an array object using the static keyword, then the object exists during the entire run time of your program.
The meaning of the static keyword is different depending on where it appears. On a local declaration (inside a function), it gives the object static storage duration, meaning that it exists for the entire execution of the program rather than being deallocated when the function returns. This means it can retain its previous value across calls to the function. An object defined outside any function already has static storage duration; in that case, the static keyword changes its linkage, so it's not visible from other source files.
Which is better, static allocation or malloc? It's impossible to say without more information.
malloc is more flexible. It will report an allocation failure by returning a null pointer; if you declare a static object that's too big, chances are your program will just crash. For an array of just 5 pointers, though, you probably don't need to worry about that (nevertheless, you should always check the value returned by malloc).
Defining a static object only lets you define a single object for each name. malloc lets you build dynamic structures. It also lets you decide at run time how many elements an array needs.
A third alternative is to define an object locally, inside some function definition, without the static keyword. In that case the object will exist only inside that function (or even inside a block), and will be automatically deallocated when the function returns.
Without knowing what you're going to do with your pointer array, we can't tell you how it should be declared and allocated. If you can declare it as a local variable inside some function, you probably should. If you can't, well, don't.

Related

When returning pointers, when does data need to be static?

I noticed something that I'd like an answer to regarding pointers and variables, it's not really a problem but I'd like to understand the details. To put it simply, to bypass using global variables, I've been starting to have functions return pointers to the data inside the function. And sometimes, that data needs to be static, other times it doesn't.
For example, let's say I have a function that creates a 2d char array, populates it with 'a' and returns a pointer pointing to that array. When the caller tries to use that pointer to access and modify the memory where the 2d array was, random data is there instead of the 2d array's contents. I found out that declaring the 2d array as static fixes this, because the array's contents are saved outside of its scope.
Now on the other hand, let's say I have a function that declares a struct, and initializes it with values. The function then returns a pointer to that struct variable. The caller should have nonsense data when trying to access the struct's values through the pointer but interestingly, it doesn't. I would think that like in the case of the 2d array, after the function call, since the struct is not static, the data at that memory should be freed. However, it's not like that, instead I can access all the struct's elements through the pointer despite it not being static.
Overall, after a function is finished, the caller can access and modify the data of variables created in that function as long as that data was static (in the 2d array case) but sometimes the data of variables is retained outside of scope despite not being labeled static (struct case). Why?
Your observations about data in a two-dimensional array of char or a struct appearing to persist or not after a function returns are the results of happenstance, not behavior defined by the C standard, and you may not rely on them. They were merely artifacts of how your C compiler behaved in particular circumstances. They may change in other circumstances and may not be relied on.
Whenever you provide an object to be used after a function returns (as by returning a pointer to the object), it must not have automatic storage duration. It may have static storage duration, allocated storage duration, or thread storage duration.
First, let us clarify some terminology. This is important for understand the concepts. The C standard does not use the term “global variables”. It generally does not use “variable” to describe object and does not use “global” for them at all. What you think of as a variable is, in the C standard, an identifier and an object. The identifier is the name of the object, and the object is a region of data storage that can represent values.
Whether the C standard guarantees an object can be used at a certain time depends on the object’s lifetime. Lifetime is when during program execution the object exists in the C model of computing. Lifetime is determined in part by its storage duration. The storage duration depends on how and where the object was defined or created.
Lifetime is also affected by the scope of an object’s identifier. Scope is where in the source code an identifier is visible (can be used). There are relationships between scope and lifetime, but they are distinctly different things.
There are four storage durations (and a special temporary storage duration, which I will not discuss here):
If an identifier is declared with _Thread_local, its object has thread storage duration. Its lifetime starts when the thread is created and ends when execution of the thread ends. So it can be used after a function returns as long as its thread is still executing.
Otherwise, if an identifier is declared with static or with extern or outside of any block or list of function parameters (effectively outside of any function), its object has static storage duration. It exists for the entire execution of the program, so it can be used any time during execution.
Otherwise, for any identifier for an object (rather than a type definition, function, or such), its object has automatic storage duration. It is associated with the statement block it is declared in. (A block is a sequence of statements inside braces, { ... }. This can be the main block that defines a function or a block nested within it.) Its lifetime ends when execution of the associated block ends. The C standard makes no guarantee about what happens when you attempt to use an automatic object after execution of its block ends.
Note that when a function calls a subroutine, execution of the function, including the blocks within it, is suspended temporarily, but it is not ended. (Execution ends when the function returns, or special routines like abort, exit, or longjmp are called.) This means that the object still exists while the subroutines are executing. This is true even though the source code in the subroutines has a different scope than the calling function.
Because of the above, statements that say you cannot use objects outside of their scope are false. Scope is not the determining factor in whether an object may be accessed. Lifetime is.
For the fourth storage duration:
Objects with allocated storage duration are created by malloc, calloc, realloc, and aligned_alloc and do not have names (identifiers). An allocated objects extends from when it is allocated to when it is deallocated. So, if a function allocates an object and returns a pointer to it, that pointer may be used to access the object until the object is deallocated.

When/where are local arrays allocated?

https://www.gnu.org/software/libc/manual/html_node/Memory-Allocation-and-C.html describes automatic allocation of local variables. I understand that local variables are commonly allocated on the stack. I can imagine how an int might be allocated on the stack; just push its value. But how might an array be allocated?
For example, if you declare an array char str[10];, does that 10 bytes of space go on the stack, or is it allocated somewhere else, and only the str pointer is pushed to the stack? If the latter, where is the 10 bytes of space allocated?
Furthermore, when exactly are local variables, including arrays, allocated? I commonly see heap allocation referred to as "dynamic allocation", implying that automatic variables are not dynamically allocated. But automatic variables may be declared within flow-of-control constructs and function bodies, so the compiler can't possibly know before runtime exactly how much space will be occupied by automatic variables. So automatic variables must also be dynamically allocated, right?
Edit: I would like to emphasize the first half of this question. I am most interested in understanding when and where the space for local arrays is allocated. On the stack? Somewhere else?
Edit 2: I made a mistake when I originally included the C++ tag for this question. I meant to ask only about the C language and its implementations. I apologize for any confusion.
In the C 2018 standard, clause 6.2.4, paragraphs 6 and 7 tell us about the lifetimes of objects with automatic storage duration. Paragraph 6 covers such objects that are not variable length arrays:
… its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time.
Thus, if we have this code:
{
PointA;
int x = 3;
PointB;
}
then x exists in the C model as soon as execution reaches PointA—its block was entered, and that is when the lifetime of x begins. However, although x already exists at PointA, its value is indeterminate. The initialization only occurs when the definition is reached.
Paragraph 7 tells us about variable length arrays:
… its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.
So, if we have this code:
{
PointA;
int x[n]; // n is some variable.
PointB;
}
then x does not exist at PointA. Its lifetime begins when int x[n]; is reached.
Keep in mind this existence is only in terms of C’s abstract model of computing. Compilers are allowed to optimize code as long as the observable results (such as output of the program) are the same. So the actual code generated by a compiler might not create x when the block is entered. (It might not create x at all; it could be optimized away completely.)
For example, if you declare an array char str[10];, does that 10 bytes of space go on the stack, or is it allocated somewhere else, and only the str pointer is pushed to the stack? If the latter, where is the 10 bytes of space allocated?
In general, the array's storage is allocated on the stack, just like any other local variable. This is compiler and target-specific. Even on a x86_64 machine, a 4 billion byte array is probably not allocated on the stack. I'd expect one of: a compile error, a link error, a runtime error, or it works somehow. In the last alternative, it might call new[] or malloc() and leave the pointer to the array on the stack in place of the array.
Notice that the array's allocation and its pointer are the same thing, so your addition of allocated somewhere else, and only the str pointer wording might indicate confusion. The allocation occurs and the name for it are not independent data.
What you ask for is depends on the language implementation (the compiler). To answer your question, this is (a simplified overview of) what compilers usually do for compiled languages (like C/C++):
When the compiler finishes parsing a function, it keeps a symbol table of all local variables declared in this function, even those declared "syntactically" during the instruction flow of the function (like local loops variables). Later, when it needs to generate the final (assembly) code, it generates the necessary instructions to push (or just moves the stack pointer) a sufficient space for all local variables. So, local loop variables, for instance, are not allocated when the loop starts execution. Rather, they are allocated at the beginning of the execution of the function containing the loop. The compiler also adds instructions to remove this allocated stack space before returning from the function.
So, automatic variables, like your char array, is totally allocated on the stack in this (common) scenario.
[EDIT] Variable length arrays (before C99)
The discussion above was for arrays having lengths known at compile time like this:
void f () {
char n[10];
....
}
If we stay in C language terms (before C99), variable-length arrays (arrays whose lengths are not known at compile-time, but rather at runtime) are declared as a pointer like this:
void f() {
char *n;
... //array is later allocated using some kind of memory allocation construct
}
This, in fact, just declares a pointer to the array. Pointers size is known to the compiler. So, as I said above, the compiler will be able to reserve the necessary storage for the pointer on the stack (just the pointer, not the real array) regardless of what will be the size of the array at runtime. When the execution reaches the line that allocates the array (using malloc, for instance), the array storage is dynamically allocated on the heap, and its address is stored in the local automatic variable n. In languages without garbage collection, this requires freeing (deallocating) the reserved storage from the heap manually (i.e. the programmer should add an instruction to do it in the program when the array is no longer needed). This is not necessary for constant-sized array (that are allocated on the stack) because the compiler removes the stack frame before returning from the function, as I said earlier.
[EDIT2]
C99 variable length arrays cannot be declared on the stack. The compiler must add some code to the resulting machine code that handles its dynamic creation and destruction at runtime.

Can I use & operator to get a valid pointer in a function even if the function has returned in golang

some code as below
type TUser struct {
Name string
Addr string
}
var UserMap map[int]*TUser //save TUser pointer to map
func LoadUsers() {
... ...
//assume "row" contains the results of table "users" from db
UserMap[0] = &TUser{Name:row["name"], Addr:row["addr"]}
}
My question is:
After the function "LoadUsers" returns, is the pointer in "UserMap[0]" valid?
or it would become a wild pointer like we do the same thing in C language?
Thanks
Yes, this is perfectly valid
From the FAQ:
How do I know whether a variable is allocated on the heap or the stack?
From a correctness standpoint, you don't need to know. Each variable
in Go exists as long as there are references to it. The storage
location chosen by the implementation is irrelevant to the semantics
of the language.
The storage location does have an effect on writing efficient
programs. When possible, the Go compilers will allocate variables that
are local to a function in that function's stack frame. However, if
the compiler cannot prove that the variable is not referenced after
the function returns, then the compiler must allocate the variable on
the garbage-collected heap to avoid dangling pointer errors. Also, if
a local variable is very large, it might make more sense to store it
on the heap rather than the stack.
In the current compilers, if a variable has its address taken, that
variable is a candidate for allocation on the heap. However, a basic
escape analysis recognizes some cases when such variables will not
live past the return from the function and can reside on the stack.

Can you define an array on the stack and pass the pointer to a global variable?

I'm programming C on a microchip that doesn't support any memory allocation commands, but it does like pointers (of course). So my question is:
Is there a way to define an array within a function, and pass the pointer to that array back to a global variable?
This would be a way to have a dynamic memory use WITHOUT malloc, realloc, or calloc. Essentially stack memory being passed back to global WITHOUT it destroying itself. I'm assuming that the alloc commands are specifically needed to ensure it doesn't get destroyed, but I wanted to check and see if there was a way around this.
Yes you can declare arrays in functions. The memory for the array will be on the call stack - though be careful, no malloc is often accompanied by a small stack.
Yes, you can give the address of a locally declared array to a globally declared pointer.
Yes it can be a handy source of dynamic memory in some circumstances, but whether you are declaring a local array or calling the much maligned alloca function the result it the same.
But, the memory is only safe until you return from the function the array is in, so you can't turn this into a malloc style thing, but rather only generate memory/scratch for your call children.
You would need to define a huge global array to reserve a big chunk of memory then use that array instead. If you prefer you can also write some simple alloc/free function to allocate/free blocks from that array.
Stack memory will be reused by the next function call. So it is not possible for you to keep anything after the function returns. Of course, if you know your function won't return while that variable is used (for example, a local variable of the main function), then it's safe to pass the pointer to that variable around.
You could define the array as static in the function and assign the value to a global pointer. Not sure I would call this a good programming practice.
Note that this only gets you 1 copy of the array so subsequent calls to your function won't create additional instances of your array. In which case I would ask why don't you just make the array global in the first place?
Do you mean something like this?
char* x;
int main(int argc, char** argv) {
static char foo[80];
x = foo;
// ...
}
This puts your buffer in the BSS segment. If you want it to remain on the runtime stack, get rid of the static.
foo has automatic storage (basically, it's size is fixed), but you now have a globally visible pointer to it.
It will hold until main returns, which presumably, is the end of your process and you don't need it anymore.
If you want to have truly dynamic memory, you'll have to write your own memory allocator, as suggested in the comments.
It's possible to store the address of an object with automatic storage duration (your array "on the stack") in a global variable, but this does not in any way increase the lifetime of the object. It still ceases to exist when execution of the block in which it's declared ends. And after it ceases to exist, any further use of the pointer you stored in your global variable would result in undefined behavior.
The main problem is function calls and how calls affect stack. On IBM architecture, simply, current EBP pushed to stack, caller stack frame is saved to EBP and callee parameters pushed to stack(generally). On return pushed EBP is poped and stack allocated parameters could be overwritten by caller, that area is free to use since callee is returned.
When you some how dynamically allocate some space on stack, it's a possibility to overwrite that space somewhere in time at a function call which has some wide veriaty of parameters or recursive calls. This is why all dynamic allocations happens in Heap and heap management is at the hands of operating system. Since malloc (etc) is o.s. wrappers for heap allocations you do not need to worry about that management, o.s. will take it care for you.
If you want to achieve dynamic allocations on stack you need to go with assembly. Make sure allocate enough space before a function call at the caller site and take that space back when caller will be returned to its caller. And that organisation would be a brainfk i guess..
A simple way to allocate memory on the "stack", pass its address to a global memory.
A potential reason to do so would be to create a "State" (Set of data), but to not have to pass it to sub-functions as the nesting could be very deep and stack savings may be had. The price in that multi-threaded applications could not use Function() safely.
Notice that anything that calls Function() should not use State.
static char *State;
static int FunctionFoo_Helper(void) {
if (*State != '\0') {
// Do _something_ more interesting than simply print
printf("%c", *State++);
FunctionFoo_Helper();
}
}
void Function(size_t n) {
char Array[n]; // Variable size array
// As to if the system put this on the stack or elsewhere is system dependent.
Populate Array(Array);
Array[n-1] = '\0';
State = Array;
FunctionFoo_Helper();
}

static objects vs. stack- & heap- based objects

I came across the following definition:
A static object is one that exists from the time it is constructed and created until the end of the program. Stack- and Heap- based objects are thus excluded. Static objects are destroyed when the program exits, i.e. their destructors are called when main finishes executing.
Why are stack- and heap- based objects excluded???
Here is what I know about stacks and heaps: The stack is the part of the system memory where all the variables are stored before run-time. The heap is the part of the system memory where all the variables are stored during run-time, e.g. dynamically allocated memory. This means that if I declare an integer variable i in my code and assign the value of say 123 to it, then that will be stored in my stack, because the compiler knows the value during the compile time (before run-time). But if I define a pointer variable and want to initialize it somewhere else, then that will be stored in my heap, since it is unknown to the compiler at the compile time.
There are several storage durations:
Static → whole program lifetime
Automatic (stack) → until the end of the current function
Dynamic (heap) → until it gets explicitly ended (via delete)
"A static object is one that exists from the time it is constructed and created until the end of the program. Stack- and Heap- based objects are thus excluded."
Why are stack- and heap- based objects excluded???
They are "excluded" because they do not exist from the time it is constructed and created until the end of the program.
None of this contradicts what you wrote / understand in your 2nd paragraph, though there may be nuances depending on the programming language that you are talking about.
What you've found is a poorly worded definition of static. Nothing more, nothing less.
In general, a static object is "created" by the compiler at compile time. Its behavior as to program exit is likely to be different across languages. For example, in C, there is no special handling at all (and AFAIK that's also true for Objective-C). Often these objects "live" in a read-only memory area that the compiler created and "attached" to the program. When the program is loaded into memory this read-only area is mapped into the program's memory which is a very fast operation. For example, all the static strings (as in printf("I'm a static string.");) in C are treated that way.
Then there's the stack, aka call stack, and a stack. A stack in general is just a data structure, aka LIFO (last-in-first-out). The call stack is indeed created by the OS and is normally limited in size. It stores all the information that are necessary for function call. That mean for each function call, its arguments and other info is "pushed" to the stack (put on top of the stack) and a little space for the function variables is reserved. Once the function returns, all this stuff is removed and only the return value is left (though even this is not always true, often the return value is passed in a CPU register).
You can store values to the stack, and languages like C++ even allow you to store objects on the stack. They "automatically" get cleaned once its enclosing function returns.
You can store also store a pointer to such an object living in the stack in another variable as well. But what you probably mean is that normally you create an object in the heap (e.g. via new in Java, C++, C#, etc. or alloc in Objective-C) and you get a pointer to that object in return.
Back to the start: static objects are known to the compiler at compile time, but everything that has to do with heap and stack is by definition only known at run time.

Resources