This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
How to access a local variable from a different function using pointers?
(10 answers)
Closed 8 years ago.
int*func();
int main()
{
int i;
int *ptr;
ptr=func();
for(i=0;i<10;i++)
{
printf("%d ",*ptr);
ptr++;
}
}
int* func()
{
int arr[10];
int i;
for( i=0;i<10;i++)
arr[i]=i+1;
return arr;
}
Why i am not getting my output as 1,2,3,4,5,6,7,8,9,10??
I am returning the address of the array from func() but
i am still getting junk values.
Wow - aggressive downvoting! Give the new person a chance folks!
The answer is "scope". If you compile with gcc, you get a very obvious warning:
C:\tmp>gcc test.c
test.c: In function `func':
test.c:22: warning: function returns address of local variable
The local variable is lost when the function exits and its memory allocation cleaned up.
If you want to return an array from a function you have to malloc it to create a non-local memory allocation and then return the pointer.
You're returning a pointer to a local variable, which results in undefined behaviour.
The most common way to deal with functions that return arrays is to pass in the array from the caller, e.g. fixed version of your code:
void func(int arr[]);
int main()
{
int arr[10];
func(arr);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
return 0;
}
void func(int arr[])
{
for (int i = 0; i < 10; i++)
arr[i] = i + 1;
}
Related
This question is meant to be used as a canonical duplicate for this FAQ:
I am allocating data dynamically inside a function and everything works well, but only inside the function where the allocation takes place. When I attempt to use the same data outside the function, I get crashes or other unexpected program behavior.
Here is a MCVE:
#include <stdlib.h>
#include <stdio.h>
void create_array (int* data, int size)
{
data = malloc(sizeof(*data) * size);
for(int i=0; i<size; i++)
{
data[i] = i;
}
print_array(data, size);
}
void print_array (int* data, int size)
{
for(int i=0; i<size; i++)
{
printf("%d ", data[i]);
}
printf("\n");
}
int main (void)
{
int* data;
const int size = 5;
create_array(data, size);
print_array(data, size); // crash here
free(data);
}
Whenever print_array is called from inside the create_array function, I get the expected output 0 1 2 3 4, but when I call it from main, I get a program crash.
What is the reason for this?
The reason for this bug is that the data used by the create_array function is a local variable that only exists inside that function. The assigned memory address obtained from malloc is only stored in this local variable and never returned to the caller.
Consider this simple example:
void func (int x)
{
x = 1;
printf("%d", x);
}
...
int a;
func(a);
printf("%d", a); // bad, undefined behavior - the program might crash or print garbage
Here, a copy of the variable a is stored locally inside the function, as the parameter x. This is known as pass-by-value.
When x is modified, only that local variable gets changed. The variable a in the caller remains unchanged, and since a is not initialized, it will contain "garbage" and cannot be reliably used.
Pointers are no exception to this pass-by-value rule. In your example, the pointer variable data is passed by value to the function. The data pointer inside the function is a local copy and the assigned address from malloc is never passed back to the caller.
So the pointer variable in the caller remains uninitialized and therefore the program crashes. In addition, the create_array function has also created a memory leak, since after that function execution, there is no longer any pointer in the program keeping track of that chunk of allocated memory.
There are two ways you can modify the function to work as expected. Either by returning a copy of the local variable back to the caller:
int* create_array (int size)
{
int* data = malloc(sizeof(*data) * size);
for(int i=0; i<size; i++)
{
data[i] = i;
}
print_array(data, size);
return data;
}
int main (void)
{
int* data;
const int size = 5;
data = create_array(size);
print_array(data, size);
}
or by passing the address to the caller's pointer variable and write directly to the caller variable:
void create_array (int** data, int size)
{
int* tmp = malloc(sizeof(*tmp) * size);
for(int i=0; i<size; i++)
{
tmp[i] = i;
}
*data = tmp;
print_array(*data, size);
}
int main (void)
{
int* data;
const int size = 5;
create_array(&data, size);
print_array(data, size);
}
Either form is fine.
This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 5 years ago.
#include <stdio.h>
int* createReverseArray(int *array, int size)
{
int i;
int newArray[size];
for(i=size-1; i>=0; i--)
{
newArray[i] = array[size-i-1];
}
return newArray;
}
int main(void) {
int myArray[] = {1,2,3,5,1};
int myArray2[] = {1,2,3,4,2,1};
int i;
int size = sizeof(myArray)/sizeof(int);
printf("Size: %d\n", size);
int* newArray = createReverseArray(myArray, size);
for(i=0; i<size; i++)
{
printf("%d, ", newArray[i]);
}
return 0;
}
I printed the array within the createReverseArray function and got the correct output, but when I return the pointer to the array and then try to print the results, I think it's printing pointers to each array spot? I'm not quite sure.
This returns:
Size: 5
12341002, 1, -10772231820, -1077231812, 1074400845,
newarray is an automatic local variable. It will no longer exists once function return. Returning pointer to an automatic local variable invoke undefined behaviour and in this case nothing good can be expected.
You can allocate memory diynamically and then return pointer to it
int *newArray = malloc(sizeof(int)*size);
I am writing C code to take user parameters and build an integer array from them. I ask the user to provide the array length and each element's value.
Running the following code causes an error at the printArray() function call. Following the debugger into printArray(), the Segmentation Fault itself occurs at printf("%d", intArray[i])
NOTE: The array is correctly printed when I copy the printArray() code into main() instead of making a function call. This makes me think that I have an issue with global variables and/or pointers. I am still learning C, so your guidance is appreciated.
How can I fix this? See debugger output at the bottom for more info.
void printArray();
int arraySize;
int* intArray;
int main() {
printf("Enter array length:\n");
scanf("%d", &arraySize);
int* intArray = (int*) malloc(sizeof(int)*arraySize);
printf("Enter an integer value for each array element:\n");
for (int i = 0; i < arraySize; i++) {
printf("Enter element %d:\n", i);
scanf("%d", &intArray[i]);
}
printArray();
return 0;
}
void printArray() {
printf("[");
for (int i = 0; i < arraySize; i++) {
printf("%d", intArray[i]);
}
printf("]\n");
}
I think you have redeclared intArray variable in main()
int* intArray = (int*) malloc(sizeof(int)*arraySize);
by doing this, the scope of this variable is only in the main function and printArray() does not know about this definition. So printArray() tries to access intArray variable which you have declared globally(which does not have definition) and thus leading to segmentation fault.
So just give intArray = (int*) malloc(sizeof(int)*arraySize);
Here is my code that works. The function initializes the array, a, to values 0 - 3
int main(void)
{
int a[4];
pointer(a);
return 0;
}
void pointer(int* a)
{
int *p, i;
p = a;
for(i = 0; i < 4; i++)
{
*a++ = i;
printf(" %d", p[i]);
}
}
But when I combine it all into main(), it no longer works.
int main(void)
{
int a[4], *p, i;
p = a;
for(i = 0; i < 4; i++)
{
*a++ = i;
printf("%d", p[i]);
}
return 0;
}
Instead, it prints out memory addresses or something. It works when I dynamically allocate a[], so I'm guessing it has something to do with the way a[] is managed in memory. Can someone tell me why the second main() doesn't work?
In the function pointer, the argument a is a pointer. But in main, a is an array, you can't modify an array name, so *a++ = i is invalid.
I can't even compile your code, and the error illustrates why:
$ gcc -o foo foo.c
./foo.c:9:11: error: cannot increment value of type 'int [4]'
*a++ = i;
~^
1 error generated.
You aren't actually using a pointer in your code at all. If you change it as follows, it works as you expect:
#include <stdio.h>
int main(void)
{
int a[4], i;
int* p = a;
for(i = 0; i < 4; i++)
{
*p++ = i;
printf("%d", a[i]);
}
return 0;
}
C arrays decay into pointers in some circunstances, but they aren't pointers. Use p instead of a.
It works when you dynamically allocate a because malloc() returns a pointer, not an array.
you should know the differences between array and pointer.I suggest .
In function,the array you put in will turn to pointer(point to first element of array),it's a variable of pointer,so you can do increasement,in main,a is a address of first element,it's constant,so you can't change.you should change pointer p.
In functions you'r passing the array address point to a pointer. and pointer is accessing each variable when u increment it. this is called a walking pointer.
but in case when u use it in main you'r assuming that array is a simple . Think of an array declared by compiler like
int *const array;
so when you try to increment it. it pops an error. so use one more Walking pointer inside
main so u traverse the array
This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 9 years ago.
Here is my code:
int *myFunction()
{
int A[3] = {1,2,3};
return A; //this will return the pointer to the first element in the array A
}
int main (void)
{
int A[3];
A = myfunction(); //A gets the return value of myFunction
for(int j=0; j==2; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
printf("%d",B);
return 0;
}
But this does not work because the A that is returned is not the actual vector. How do I get the actual vector {1,2,3} in the main function?
The function myFunction allocates A, but this allocation only exists within the scope of the function. When the function returns the memory holding A is destroyed. This means that the function is returning a pointer to memory that has not been un-allocated.
The problem is that the variable A does not persist outside the function. You could use a global variable or pass a pointer to the buffer into myFunction
Global variable method:
static int A[3];
int* myFunction()
{
A[0] = 1; A[1] = 2; //etc
return A;
}
In this example, because A is a global, the memory pointed to by A persists throught your program's entire life time. Therefore it is safe to return a pointer to it...
As a side note, global variables should probably not be used in this way... it's a little clunky. The use of the static keyword means that A will not be accessible outside of this module (C file).
Pointer method:
void myFunction(a[3])
{
a[0] = 1; a[1] = 2; //etc
}
int main()
{
myA[3];
myFunction(myA);
// and continue to print array...
}
In this example the main() function allocates myA. This variable exists whilst the function is executing (it's an automatic variable). A pointer to the array is passed into the function, which fills the array. Therefore the main() function can get information from myFunction().
Another way to make the variable myA persist would be to allocate it on the heap. To do this you would do something like int *myA = malloc(sizeof(int) * NUMBER_OF_INTS_IN_ARRAY. This memory will then persist until you specifically desctroy it using free() or you program ends.
int A[3] = {1,2,3}; is being created on the stack, this is, it is a local array and it's memory can be used again after myFunction executes. You have to either make int A[3] static within myFunction or by placing it outside of all functions. Another option would be to create int A[3] within main and pass the address of A to myFunction so myFunction can directly modify the contents of A.
As is, your code isn't close to working anyway... your for loop is broken, you have undefined variables in main, you have function name mismatches, and your print isn't going to do what you want anyway...
The big problem as that you've got undefined behavior going on, you can't access A[] outside of the function where it was locally defined. The easiest way to rectify that is to use dynamic memory, malloc() some memory for A in your myFunction then use the values in main and free() the memory when you're done.
Here's the example fixing your other syntax issues:
int *myFunction()
{
int *A;
A = malloc(3 * sizeof(int));
A[0] = 1;
A[1] = 2;
A[2] = 3;
return A;
}
int main (void)
{
int *A = myFunction(); //A gets the return value of myFunction
int B[3] = {0, 0, 0};
int j;
for(j=0; j<3; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
free(A);
printf("%d",B[0]);
return 0;
}
Pass the array to be filled as argument to the initisliser function along with its size:
size_t myFunction(int * A, size_t s)
{
int A_tmp[3] = {1,2,3};
size_t i = 0;
for (; i < s && i < sizeof(A_tmp)/sizeof(A_tmp[0]); ++i)
{
A[i] = A_tmp[i];
}
return i;
}
Then call it like so:
int main()
{
int myA[3];
size_t s = sizeof(myA)/sizeof(myA[0]);
size_t n = myFunction(myA, s);
if (n < s)
fprintf(stderr, "Caution: Only the first %zu of %zu elements of A were initialised.\n", n, s);
// and continue to print array...
}
#include <stdio.h>
int (*myFunction(void))[3]
{
static int A[3] = {1,2,3};
return &A;
}
int main (void){
int (*A)[3], B[3];
A = myFunction();
for(int j=0; j<=2; j++)
{
B[j] = 2 * (*A)[j];
}
for(int j=0; j<3;++j)
printf("%d ", B[j]);
return 0;
}