C programming, using memory - c

I have a main function and it has global array
unsigned int MainArray [800];
then the program calls function which has local
unsigned int FunctionArray [400];
and I have not enough space in memory.
However the MainArray is not used while the function is called and inside data is not important, also FunctionArray is not required after function is used.
Is any way how FunctionArray can be declared over same memory allocation that the MainArray uses?
When I declare MainArray [800]; inside main then later on other functions can’t access the data.

If you want the data from the mainArray on the later state of the program, i.e, after the execution of the function, then, you can't say the "data of the mainArray is not important while the function is called" because it's important afterwards.
If you are thinking of a way for "FunctionArray can be declared over same memory allocation that the MainArray uses", then even if there WOULD HAVE BEEN a way, the data of mainArray would have been destroyed which you will be needing in later program as you said.
If you don't need the data of main in later state, you can do one thing,
define the array as a pointer outside the main(),
unsigned int * MainArray;
then allocate it dynamically with required size in main(). When the need of the array is finished, just free the memory. The space will be available for farther allocations.
If you need the mainArray after the execution of the function having the functionArray,and not before; just allocate the memory for the mainArray after the function has been executed. and use the local functionArray as the pointer as well, in the function and free the memory before the control gets back from the function. This way your program doesn't occupy the space for the mainArray while executing that function, and when the function is done executing, functionArray is not occupying any space.
But if you need mainArray, both before and after the function execution, I think there is no way you could solve the memory problem..

If you declare a variable inside main(), this doesn't make it a global variable, it's a variable local to main(). Unless you pass a pointer to it around, other functions can't access it.
You seem to ask for a global array. Just declare it outside main() and every function can access it.
Global variables, however, should be carefully considered since they vulnerate the rule of information hiding/encapsulation (that may be the reason nobody taught you they exist), nevertheless there are sometimes good reasons to use them (especially on devices where memory is a scarce resource which seems to be the case for you).

you can use the arrays base pointer to access the array's memory space in other functions.
you declare a array
unsigned int MainArray [800];
Then if you pass MainArray as parameter to function and receive it as,
returnType somefunction(unsigned int * FunctionArray, ...)
{
}
Then you can use the same memory in both main function and array. but in function make sure that you access FunctionArray only within its size limit of 400. This will enable you to access same memory in both functions as array.
You can even allocate memory to arrays dynamically, if they are needed in program in sequence and not at same time. you can use malloc or alloca.

Related

where are the variable stored that are initialized in main function in c?

In C language, I know that when a variable is dynamically initialized using malloc, it is stored in heap area. But where is the memory allocated when declaration of below kind is done and variables are initialized later.
int a[26];
or
int a[n]; //n is a variable and each element in array a is later initialized through a for loop.
My initial understanding is that like in java, here also all variables declared in main function are stored in stack area. My doubt is- Say, there is a function that takes the address of array "a" and changes its contents. To change the contents of "a", it should be able to access each element's address in "a". As the function itself is getting executed in the stack space on the top of main function, it cannot access array "a"'s contents directly. So, my doubt is where is array "a"'s memory allocated?
Usually, int a[n]; is called a variable length array, and the storage allocation is compiler dependent.
For example, gcc allocates VLAs in stack memory.
FWIW, the local variables are also usually stored in stack memory (minus the compiler optimization, if any).
arrays can be almost any length, they can be used to store thousands or even millions of objects, but the size must be decided when the array is created. Each item in the array is accessed by an index, which is just a number that indicates the position or slot where the object is stored in the array.
Array size stored in the computer physical memory

Arrays as parameters and inputs in c

Okay so I understand that a function cannot return an array but rather a pointer to an array but I had other questions.
Does the array that I am going to be pointing to need to be declared outside the function?
If I dynamically allocate memory for an array in this function, would I able to free it within a function that called this function?
Say intended to loop this function in a for loop would this be acceptable/ideal as long as I freed the memory before calling It again.
yes you can free the dynamically allocated memory for the array from the calling function. it is fine provided you allocated memory on heap using function like malloc(). Then you can free that memory from any function if you have a pointer to that memory using free().
You can return an array of a function if you know
that the memory exists further and you´re freeíng it if nessecary.
Rough possible cases:
A non-dynamic array outside of the function can be passed to it.
The function could return the same array (it makes no sense,
beauce the caller should have it alaready, but it is possible)
A non-dynamic array of a function can NOT be returned to the outside
because it will cease to exist at the end of the function.
A dynamic allocated array from anywhere can be passed/returned as much as you want,
as long you know when and where it will be free´d
(ie. don´t forget the free and don´t access it after the free)

Using static instead of malloc - C-language

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.

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();
}

Arrays scoping in threads

How are arrays scoped in C? When do they ever get destroyed? (Note, also talk about if they can be passed even in p_threads)
They're scoped just like normal variables:
// in a function
int arrayA[300];
{
float arrayB[100];
// arrayA and arrayB available here
}
// arrayB out of scope, inaccessible.
// arrayA still available.
If you were to pass the array to a function, it would be valid as long as the array was still in scope at the calling site.
Arrays are scoped like any other primitive, struct or union. Nothing ever gets destroyed in C, though arrays can go out of scope.
Also, just like other types, arrays can be allocated on the heap by calling malloc() to allocate enough space to hold the desired number of elements, and treating the returned void * as a pointer to the first element. Such an array will be valid until you call free().
WRT Pthreads, again the rules are just as for any other type. If you define an array as an automatic (function-scope) variable, it will go out of scope as soon as the function returns; you cannot safely pass a pointer to such an array to another thread. But if you allocate an array on the heap, then you can pass a pointer to this array (to anything inside the array) anywhere you please, including another thread. Of course, you still need to ensure thread-safe access to the contents using appropriate synchronisation mechanisms.
There's absolutely no difference in scoping and lifetime rules between arrays and any other named entities in C language. I.e. arrays are not special in any way when it comes to scope and lifetime. They behave in that regard just like an ordinary int variable would.

Resources