I want to declare a global variable inside a main() function...
Below is what I want the program to act like
#include<stdio.h>
int a[6];
int main()
{
int n;
scanf("%d",&n);
}
I want to create an array of user given size (here n-size) and I want to access that array globally.
So instead of creating array of size '6' outside the main() function, I want to create array of 'n' size globally instead of passing array whenever function is called...
You can declare a pointer as global variable and assign buffer to that in main().
#include<stdio.h>
#include<stdlib.h>
int *a;
int main()
{
int n;
scanf("%d",&n);
a = calloc(n, sizeof(*a)); /* calloc() initializes the allocated buffer to zero */
if (a == NULL)
{
/* calloc() failed, handle error (print error message, exit program, etc.) */
}
}
You may want to use an array allocated into the heap by using malloc
#include<stdio.h>
int *a;
int main()
{
int n;
scanf("%d", &n);
a = malloc(sizeof(*a) * n);
if(a == NULL) {
// malloc error
}
// use your array here
free(a); // at the end of the program make sure to release the memory allocated before
}
You cannot do that.
The closest you can get it, define a pointer in file scope (i.e., global), allocate memory to it by using allocator function (malloc() and family) and use the same pointer in other function calls as necessary. As the lifetime of the allocated memory is until deallocated programmatically (passed to free()), other functions can make use of the allocated memory.
Related
My Doubt is regarding only memory allocation so don't think about program output
#include<stdio.h>
int main(){
for(int i=0;i<20;i++){
char *str=malloc(sizeof(char)*6); //assuming length of each string is 6
scanf("%s",str);
insertinlinkedlist(str);
}
}
whenever i allocate memory here as shown above only the base address of char array will pass to linked list,and that is the memory block allocated for char array is inside main only and i am storing the base address of that array in str which is local to main and is passed to insetinlinkedlist
I want to ask whenever memory is allocated inside loop than why the number of
memory blocks(no of char arrays declared ) are created equal to n (number of time loop runs) since variable name is same we should be directed to same memory location
Note I have checked in compiler by running the loop all the times when loop runs memory the value of str is different
is The above method is correct of allocating memory through loop and through same variable "Is the method ensures that every time we allocate memory in above manner their will be no conflicts while memory allocation and every time we will get the address of unique memory block"
Now above doubt also creates a doubt in my mind
That if we do something like that
int main(){
for(int i=0;i<n;i++){
array[50];
}
}
then it will also create 50 array inside stack frame
malloc returns a pointer to the first allocated byte. Internally it keeps track of how much memory was allocated so it knows how much to free (you do need to insert calls to free() or you'll leak memory, by the way). Usually, it does this by allocating a little bit of memory before the pointer it gives you and storing the length there, however it isn't required to do it that way.
The memory allocated by malloc is not tied to main in any way. Currently main is the only function whose local variables have a pointer to that memory, but you could pass the pointer to another function, and that function would also be able to access the memory. Additionally, when the function that called malloc returns, that memory will remain allocated unless manually freed.
The variable name doesn't matter. A pointer is (to first approximation) just a number. Much like how running int a = 42; a = 20; is permitted and replaces the previous value of a with a new one, int *p = malloc(n); p = malloc(n); will first assign the pointer returned by the first malloc call to p, then will replace it with the return value of the second call. You can also have multiple pointers that point to the same address:
int *a = malloc(42);
int *b = malloc(42);
int *c = a;
a = malloc(42);
At the end of that code, c will be set to the value returned by the first malloc call, and a will have the value returned by the last malloc call. Just like if you'd done:
//assume here that f() returns a different value each time
//it's called, like malloc does
int a = f();
int b = f();
int c = a;
a = f();
As for the second part of your question:
for(int i=0;i<n;i++){
int array[50];
}
The above code will create an array with enough space for 50 ints inside the current stack frame. It will be local to the block within the for loop, and won't persist between iterations, so it won't create n separate copies of the array. Since arrays declared this way are part of the local stack frame, you don't need to manually free them; they will cease to exist when you exit that block. But you could pass a pointer to that array to another function, and it would be valid as long as you haven't exited the block. So the following code...
int sum(int *arr, size_t n) {
int count = 0;
for (size_t i = 0; i < n; i++) {
count += arr[i];
}
return count;
}
for(int i=0;i<n;i++){
int array[50];
printf("%d\n", sum(array, 50));
}
...would be legal (from a memory-management perspective, anyway; you never initialize the array, so the result of the sum call is not defined).
As a minor side note, sizeof(char) is defined to be 1. You can just say malloc(6) in this case. sizeof is necessary when allocating an array of a larger type.
I'm currently studying variable length array and automatic storage.
I have the following code that allocate memory for an variable length array myArray inside function vla, and return a pointer to the variable length array from the function.
#include <stdio.h>
int * vla(int n){
int myArray[n];
myArray[0] = 10;
myArray[1] = 11;
int * pointerToInt = myArray;
return pointerToInt;
}
int main(void){
int * pointerToInt = vla(10);
printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 10, 11
return 0;
}
I thought that variable length array belong to the automatic storage class (i.e. the memory for the variable length array will be allocated when we enter the function containing the variable length array, and the memory is automatically deallocated after the function exit)
So according to this logic, the memory allocated to myArray variable length array is deallocated after we return from vla method, but how come I can still correctly access the first and second element of the variable length array?
Is this behavior defined? or it is undefined behaviour that just happen to work?
myArray is a stack/auto variable created on the stack memory. Remember memory always exists. It is just owned by different pointers based on allocation and deallocation. The reason why you can still access same values is that the same piece of memory has not been assigned to another pointer and not been overwritten.
To evaluate it. Create another function that allocates same amount from stack but puts different values. Or add arguments in the same function and call it twice with different values. You will then see the difference.
#include <stdio.h>
int * vla(int n, int a, int b){
int myArray[n];
myArray[0] = a;
myArray[1] = b;
int * pointerToInt = myArray;
return pointerToInt;
}
int main(void){
int * pointerToInt = vla(10, 10, 11);
vla(10, 20, 21); // over write stack
printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 20, 21
return 0;
}
By the way returning stack memory from vla is not a good idea. Dynamic memory is allocated from heap using malloc family of functions.
You can still correctly access the first and second element of the variable length array because you are assigning base address of the myArray to pointerToInt. Auto variables have a life inside the block only, but in this program we are using pointer to access the data in the memory, as long as that part of stack is not allocated to any other program, we can access that part of stack. If that part of stack is allocated to some other process we will get segmentation fault as we are trying to access unauthorized memory
If we were to use malloc() in main(), we could free() that dynamic memory allocation in main().
However, if we use malloc() in a different function
and we use that function in main(), where should we call free() to release the memory allocated in that function?
I.e., in the following source code:
#include <stdio.h>
#include <stdlib.h>
int * memory_allocate_function(int);
int main(void) {
int n=5; //length of array, 5 for example.
int *my_array;
my_array = memory_allocate_function(n);
return 0;
}
int * memory_allocate_function(int n) {
int i;
int *array;
array=(int *)malloc(n * sizeof(int));
if(array == NULL) {
printf("can not allocate memory.");
return NULL;
}
// I think i can't use "free(array);" in here.
// Because I need that array in main().
return array;
}
Is this the best way to do this?
Well after you are done working with it - free the dynamically allocated memory. But design wise - you can call the free in other function also to manage it properly. It really depends. There is no hard rule for that.
For example here you should return that pointer to allocated memory and then after using it in main you can free it in main().
So the structure would be something like
int* memory_allocate_function(int n)
{
int i;
int *array;
array = malloc(n*sizeof(int));
if(array == NULL)
{
printf("can not allocate memory.");
exit(0);
}
return array;
}
Then in main()
int main(void)
{
int n=5; //length of array, 5 for example.
int *arr = memory_allocate_function(n);
// work with arr
free(arr);
return 0;
}
But yes name the function properly - if you are going to use the name memory_allocate_function function then do that only - not any other major logic should be there. This helps create a good readable code.
Note one thing - here when you called the function and then you exited the function the only local variable that contains address of it, it's storage duration ended and you can never then access the memory you allocated. This is a case of memory leak. If you are determined that you won't return the pointer to memory from the function - then work with it (in the same function or different) and then free it (Before the scope of the function ends - notice not mentioning about where you would free it, you can do it in the same function and other function also).
I can't help mentioning few things:- 1) Dont cast the return value of malloc. 2) Check the return value of malloc - in case it is NULL you would like to handle it separately. 3) The recommended signature of main() is int main(void)
Memory should be freed when it's no longer needed.
Since the array would no longer be accessible after memory_allocate_function exits (since the array isn't returned or otherwise made accessible to the outside), it should be freed before memory_allocate_function exits.
void memory_allocate_function(int n){
int i;
int *array;
array = malloc(n*sizeof(int));
if (array == NULL) {
fprintf(stderr, "Out of memory.");
exit(1);
}
// ... use the array ...
free(array);
}
If you need to malloc memory in one function and free in another, you have to somehow carefully pass the pointer to that malloced memory from the point of malloc to the point where you want to free it.
This is your responsibility to preserve the pointer value and hand it from one function to another until it reaches the point of free. If you lose that value along the way, you'll have a memory leak. A memory leak is what you have now, since you are not passing that local array pointer anywhere.
There's no "one true way" to do it, since it depends on your specific intent. For example, you can return that pointer from memory_allocate_function, receive it main and eventually free it there
int *memory_allocate_function(int);
int main()
{
int n = 5;
int *arr = memory_allocate_function(n);
...
free(arr);
return 0;
}
int *memory_allocate_function(int n)
{
int *array = malloc(n * sizeof *array);
...
return array;
}
This question already has answers here:
How is the array stored in memory?
(4 answers)
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
I am trying to implement a simple program using a header file where a function in the header file accepts an int array and returns an int array too.
In header.h:
int* point(int a[]);
In header.c:
#include<stdio.h>
#include "header.h"
int* point(int a[])
{
printf("In the point function\n");
int array[4],i;
for(int i=0;i<4;i++)
{
printf("%dth Iteration\n",i);
array[i]=a[i];
}
return array;
}
In test.c:
#include<stdio.h>
#include "header.h"
void main()
{
int *array,i;
int a[]={1,2,3,4};
printf("calling point function\n");
array=point(a);
printf("Back in the main function\n");
for(i=0;i<4;i++)
{
//SEGMENTATION FAULT HERE
printf("%d\n",array[i]);
}
}
I am getting a segmentation fault at the print loop in test.c.
You cannot return arrays from functions. When point() returns, the local array within this function goes out of scope. This array is created on the stack, and will get destroyed once the function finishes returning. All memory associated with it is discarded, and the returned pointer points to a position on the stack that doesn't exist anymore. You need to instead allocate a pointer on the heap, and return that instead. This allows array to be shared across your program.
Instead of:
int array[4];
you need to dynamically allocate a pointer using malloc():
int *array = malloc(4 * sizeof(*array)); /* or sizeof(int) */
if (array == NULL) {
/* handle exit */
}
malloc() allocates requested memory on the heap, and returns a void* pointer to it.
Note: malloc() can return NULL when unsuccessful, so it needs to be checked always. You also need to free() any memory previously allocated by malloc(). You also don't need to cast return of malloc().
Another thing to point out is using the magic number 4 all over your program. This should really be calculated using sizeof(a)/sizeof(a[0]).
You can declare this as a size_t variable in your main():
size_t n = sizeof(a)/sizeof(a[0]);
Or you can use a macro:
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
And simply call ARRAYSIZE(a) everytime you want the size of the array.
The issue has to do with the scope of the array variable that you're returning in your method. Right now you're returning array, a local variable defined in the method, point. However, once point is finished executing, all local variables within the function frame, including array will be discarded from main memory. So even though you still get a memory address from point, there's no telling what could be at that memory address. Therefore, treating array as an int array when printing out its elements will lead to a segmentation fault.
My suggestion to fix this is to allocate memory from the heap using malloc so that array lasts outside the frame of point. The solution should look like this,
int* point(int a[])
{
printf("In the point function\n");
int *array = (int *) malloc(4 * sizeof(int)); //dynamically allocate memory for 4 integers
int i;
for(i=0;i<4;i++)
{
printf("%dth Iteration\n",i);
array[i]=a[i];
}
return array;
}
You could either define array[] as a global variable, or dynamically allocate memory for it as mentioned in the above comments using malloc().
Since array[] is allocated in the function point(), it gets deleted once the function exits. Hence, a reference to the returned pointer causes a segmentation fault.
int *getAr()
{
int *a;
int i;
a=(int*)malloc(sizeof(int)*10);
for(i=0;i<10;i++)
a[i]=i;
return(a);
}
int main()
{
int *a;
int i;
a=getAr();
for(i=0;i<10;i++)
printf("%d\t",a[i]);
printf("\n");
return 0;
}
OUTPUT is:
0 1 2 3 4 5 6 7 8 9
When you malloc(), the memory is taken from the heap. Which is not unloaded when the function returns (unlike the stack).
Others have already pointed out the reason, adding a few more points to help.
Local/Automatic variables have their scope inside the function call, and not in any other function.
But here, you are returning the pointer to dynamically allocated memory, which won't be freed up after the function call, and this is the reason why the program works fine, in spite of the fact that there is a memory leak.
You will have to explicitly call free() to free up the memory you allocated using malloc().
I think you are confused in this case:
// When the array is on the stack:
int *getAr() {
int b[10]; // 'b' allocated on stack
int *a = b; // 'a' allocated on stack
return (a); // or return (b);
}
void main () {
int * a = getAr();
printf("%d \n", a[0]); // this may not give you the correct result
}
A good tutorial on stack and heap will help you:
http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
Its value is accessible inside main function because it is heap-allocated. Heap allocated data is accessible to any function in your program, opposed by stack-allocated data, which is accessible only to the function that created it due to stack unloading.
Source: http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html#sec-3
Returning pointer to automatic local variable is not allowed in C as it does not exist once function returns.
Otherwise returning pointer to static local variable and variables that allocated dynamically is allowed.