This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 8 years ago.
I was trying to pass the array address from the function to the main function that's happening perfectly. But when I dereference the address in main(), I am getting junk values. I am guessing that the variables in the array_address memory lives only within the scope of the function. If this is the case, how do you return an array generated within a function to another function?
Here's my code:
int* letssee(int something)
{
int* array_address;
int a[10], i=0;
array_address = &a[0];
for (i; i<something;i++)
{
*(array_address+i) = i;
printf("\n%p, %d",(array_address+i), *(array_address+i));
}
return array_address;
}
int main()
{
int i= 5,j;
int* catch_address;
catch_address = letssee(i);
printf("\n");
for (j= 0; j<i; j++)
{
printf("%p, %d\n", (catch_address+j),*(catch_address+j));
}
return 0;
}
you can't return an array defined in a function as it is allocated on the stack and will disappear after the function has finished. Instead you allocate memory
int *array_address = malloc(sizeof(int) * 10);
however, you have to manage the memory, meaning you have to "free" it when you are finished with it, otherwise you will leak memory
The other approach is to pass the memory preallocated into a function (whether it be via malloc or the stack or global)
int* letsee(int something, int* array_address, int count);
if you simply make the array static, you are effectively making a global variable, multiple calls to the function will return the SAME address and may cause strange behaviour if you are expecting new arrays for each call.
Related
This question already has answers here:
Returning an array from a function in C: Segmentation Fault [duplicate]
(3 answers)
How to access a local variable from a different function using pointers?
(10 answers)
Closed 4 years ago.
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#define len 10
int *randomArray(void);
int main()
{
srand(time(NULL));
int *rArray = (int *)malloc(sizeof(int) * len);
rArray = randomArray();
for (int i = 0; i < len; i++) {
printf("%d ", *(rArray+i));
}
puts("");
free(rArray);
}
int *randomArray(void)
{
int array[len] = { 0 };
for (int i = 0; i < len; i++) {
array[i] = rand() % len;
}
return array;
}
Task is to create an array of ints and have a function fill that array with random numbers. The function randomArray() works just fine, but for some reason the assignment rArray = randomArray() doesn't work correctly, although some elements of rArray are valid numbers not gibberish. Also, the last main line free(rArray); crashes the program which is just mind numbing for me, it doesn't make any sense. If I remove the line the program doesn't crash but we all know you need to free() a malloc()-ed array.
The primary problem here is, array is a local variable in the randomArray() function scope. Once the function returns, the returned address becomes invalid. Any further attempt to use the memory will lead to undefined behavior.
Moreover, from your approach, you are trying to overwrite the allocated memory by the address being returned from the function call, which will cause memory leak. Rather, change your design, pass the allocated memory to the function as the argument and just fill the elements using the rand() call.
The randomArray return a pointer to the first element of the local array array.
That pointer becomes invalid immediately once the function returns as the variable goes out of scope. Using it in any way will lead to undefined behavior.
What makes it even worse is that you reassign the pointer rArray, making you lose the original memory you allocated. That means your call to free again will lead to UB.
To solve both problems, pass the pointer and the size as arguments to the randomArray function:
void randomArray(int *array, int size)
{
for (int i = 0; i < size; ++i)
{
array[i] = rand() % size;
}
}
int *randomArray(void)
{
int array[len] = { 0 };
//...
return array;
}
array goes out of scope at } and accessing this returned pointer is UB.
Moreover rArray = randomArray(); leaks memory since now you cannot free the malloc'd memory. You should pass the rArray to a function, which will be responsible for filing it.
In randomArray() function, you are returning the array that is allocated on stack. That array will be freed when returning from randomArray() function. Instead, you can do this:
void randomArray(int * array)
{
// Remove this int array[len] = { 0 };
for (int i = 0; i < len; i++) {
array[i] = rand() % len;
}
// Remove this .. return array;
}
And call randomArray(rArray) from main()
This question already has answers here:
Initializing a pointer in a separate function in C
(2 answers)
C Programming: malloc() inside another function
(9 answers)
Closed 5 years ago.
In the main function, I have some null pointer like
double *data_1;
This pointers are passed as argument to other function which determine how many components must have data_1 and uses malloc to assign a memory block and store information:
void function(double *data) {
...
data = (double *) malloc((size_t) (Ndata) * sizeof(double));
for(i = 0; i < (Ndata); i++) {
data[i] = sys->points[i][coordinate];
}
}
This code isn't working. I used GDB to examine bug and I encounter that inside function() the assignment works, but when execution returns to the main() function, the array data_1 wasn't modified although the memory to which it points is exactly the same to which points "data" argument in function().
Why is this happening?
The pointer you passed to your function is passed by value. It is copied to the parameter data. Inside you are allocating memory to data which will make it to point to the allocated memory instead of the pointer you passed. Any modification done to this pointer is not reflected to the pointer you passed. You need to return the pointer to the allocated memory.
double *function() {
...
double *data = malloc((size_t) (Ndata) * sizeof(double));
for(i = 0; i < (Ndata); i++) {
data[i] = sys->points[i][coordinate];
}
return data;
}
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.
Save pointer to array in struct.
I would like to store the pointer to array of int into struct but I am having trouble.
Below my code with commentaries:
typedef struct _index {
int *data;
} Index;
void adder(struct _index *s){
int i;
int arr[maxint];
for(i=0; i<maxint; i++) {
arr[i] = i+42;
}
//i got a gibberish
//s->data = arr;
//works fine
s->data = (int *) malloc(maxint * sizeof(int));
s->data = memcpy(s->data, arr, maxint * sizeof(int));
)
int main() {
Index n;
int i;
//this method also works.
//int arr[maxint];
//for(i=0; i<maxint; i++) {
// arr[i] = i+42;
//
//}
//n.data = arr;
adder(&n);
for(i=0; i<maxint;i++) {
printf("%d-", n.data[i]);
}//testing
return 0;
}
when i make assignment, i got strange numbers:
117-118-119-120-12-0-22-2292964-0-2293008-127-0-129-130-131-0-0-0-0-0-0-138-0
but if i use malloc and memcpy all works fine
You got gibberish in your first case, because you tried to "return" the address of a local variable from a function through the pointer. Once the function finishes execution, the int arr[maxint]; won't be valid. In other words, after adder() finishes execution, int arr[maxint]; goes out of scope and it's lifetime is over. So, the (returned) pointer becomes invalid and using that further in the caller function will result in undefined behaviour.
Solution:
As you've done correctly, using dynamic memory.
use static variable (not a good approach, but possible).
In both the aforesaid approach, the lifetime of the variable ( static arr array/ malloc()ed memory) is not limited to function scope and thus, the pointer to the meory will be vaild in the caller function.
The array arr in the adder() function is on the stack and only exists as long as the code in that function is running. Once adder() returns that memory is re-used by the rest of the program and its content overwritten.
int arr[] is placed on the stack and gets removed from the stack when it goes out of scope. So you will point to garbage.
It works fine if you include it in your main because that way it hasn't gone out of scope yet.
Malloc works because you allocate memory and not just place it on the stack.
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.