How to access a local variable from a different function using pointers? - c++

May I have any access to a local variable in a different function? If so, how?
void replaceNumberAndPrint(int array[3]) {
printf("%i\n", array[1]);
printf("%i\n", array[1]);
}
int * getArray() {
int myArray[3] = {4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
The output of the piece of code above:
65
4202656
What am I doing wrong? What does the "4202656" mean?
Do I have to copy the whole array in the replaceNumberAndPrint() function to be able to access it more than the first time?

myArray is a local variable and as thus the pointer is only valid until the end of its scope (which is in this case the containing function getArray) is left. If you access it later you get undefined behavior.
In practice what happens is that the call to printf overwrites the part of the stack used by myArray and it then contains some other data.
To fix your code you need to either declare the array in a scope that lives long enough (the main function in your example) or allocate it on the heap. If you allocate it on the heap you need to free it either manually, or in C++ using RAII.
One alternative I missed (probably even the best one here, provided the array is not too big) is to wrap your array into a struct and thus make it a value type. Then returning it creates a copy which survives the function return. See tp1's answer for details on this.

You can't access a local variable once it goes out of scope. This is what it means to be a local variable.
When you are accessing the array in the replaceNumberAndPrint function the result is undefined. The fact it appears to work first time is just a fortunate coincidence. Probably the memory location you are pointing to is unallocated on the stack and is still correctly set for the first call, but the call to printf then overwrites this by pushing values onto the stack during its operation which is why the second call to printf displays something different.
You need to store the array data on the heap and pass a pointer, or in a variable that remains in scope (e.g. a global or something scoped within the main function).

Try something like that. The way you do it "kills" myArray cause if it locally defined.
#include <stdio.h>
#include <stdlib.h>
void replaceNumberAndPrint(int * array) {
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n" , array[2]);
free(array);
}
int * getArray() {
int * myArray = malloc(sizeof(int) * 3);
myArray[0] = 4;
myArray[1] = 64;
myArray[2] = 23;
//{4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
More : http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/
Edit: As Comments correctly pointed out: A better way to do it would be that :
#include <stdio.h>
#include <stdlib.h>
void replaceNumberAndPrint(int * array) {
if(!array)
return;
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n" , array[2]);
}
int * createArray() {
int * myArray = malloc(sizeof(int) * 3);
if(!myArray)
return 0;
myArray[0] = 4;
myArray[1] = 64;
myArray[2] = 23;
return myArray;
}
int main() {
int * array = createArray();
if(array)
{
replaceNumberAndPrint(array);
free(array);
}
return 0;
}

myArray goes out of scope as soon as you leave getArray. You need to allocate space for it on the heap instead.

Your code invokes Undefined Behaviour because myArray goes out of scope as soon as getArray() returns and any attempt to use (dereference) the dangling pointer is UB.

Local variables go out of scope upon return, so you can't return a pointer to a local variable.
You need to allocate it dynamically (on the heap), using malloc or new. Example:
int *create_array(void) {
int *array = malloc(3 * sizeof(int));
assert(array != NULL);
array[0] = 4;
array[1] = 65;
array[2] = 23;
return array;
}
void destroy_array(int *array) {
free(array);
}
int main(int argc, char **argv) {
int *array = create_array();
for (size_t i = 0; i < 3; ++i)
printf("%d\n", array[i]);
destroy_array(array);
return 0;
}
Alternatively, you can declare the array as static, keeping in mind the semantics are different. Example:
int *get_array(void) {
static int array[] = { 4, 65, 23 };
return array;
}
int main(int argc, char **argv) {
int *array = get_array();
for (size_t i = 0; i < 3; ++i)
printf("%d\n", array[i]);
return 0;
}
If you don't know what static means, read this question & answer.

Right way to do this is as follows:
struct Arr {
int array[3];
};
Arr get_array() {
Arr a;
a.array[0] = 4;
a.array[1] = 65;
a.array[2] = 23;
return a;
}
int main(int argc, char **argv) {
Arr a = get_array();
for(size_t i=0; i<3; i++)
printf("%d\n", a.array[i]);
return 0;
}
To understand why you need to do this, you need to know how sizeof(array) works. C (and thus c++) tries hard to avoid copying the array, and you need the struct to go past that. Why copying is needed is because of scopes -- the get_array() function's scope disappears and every value still needed from that scope will need to be copied to calling scope.

C++ solution:
"May I have any access to a local variable in a different function? If so, how?"
The answer is no, not after the function has ended. Local variables are destroyed at that point.
In C++ the way to deal with returning arrays is to manage them in a container like a std::array (fixed size) or a std::vector (dynamic size).
Eg:
void replaceNumberAndPrint(const std::array<int, 3>& array) {
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n", array[2]);
}
std::array<int, 3> getArray() {
std::array<int, 3> myArray = {4, 65, 23};
return myArray;
}
In the second function the returned value is optimized by the compiler so you don't pay the price of actually copying the array.

In this code you have used pointer to local objects but when a function returns all local variables goes out of scope. If you will allocate memory (using malloc() function for allocation) then no data will be lost or overwrite.
int* getArray(int size) {
int *myArray = (int*)malloc(size*sizeof(int));
myArray[0] = 4;
myArray[1] = 65;
myArray[2] = 23;
return myArray;
}
int main() {
int i;
int *vector = getArray(3);
for(i=0;i<3;i++)
{
printf("%i\n",vector[i]);
}
getch();
return 0;
}
This code will print all the array elements and no overwritten will be happened.

Static ..or.. Global within your .c will do the trick ;)
However the entire time the program will occupy those 3 bytes BUT you avoid doing malloc on simple things like this (malloc recommended for big arrays)
On the other hand if the outside function modify the pointer, then the internal 'myArray' will be modified cause it points to it, that's it
int myArray[3];
int * getArray() {
myArray[0] = 4;
myArray[1] = 65;
myArray[2] = 23;
return myArray;
}

Related

How to free memory allocated in a function without returning its pointer?

I have a function like this:
int fun(){
int* arr = new int[10];
for(int i = 0; i < 10; i++){
arr[i] = 5;
}
delete[] arr; //
return arr[6];
}
int main(){
std::cout << fun();
return 0;
}
What am i going to do is to free the memory whick is pointed to by the pointer arr. But the function is not returning pointer arr. So i tryed to free it inside the function.
It won't print anything if delete[] arr is above return arr[6] (Using Visual Studio 2019).
But if return arr[6] is above delete[] arr , would the memory be freed or this sentence be skipped?
Or should i declare arr inside main() then free it in main()?
Unless it's for academic purposes, you rarely see a C++ program using manual memory allocation, you don't need to do it since you have a set of containers in the STL containers library that do this memory management reliably for you. In your particular example, a std::vector is recommended.
That said, to answer your question:
It won't print anything if delete[] arr is above return arr[6] (Using Visual Studio 2019).
If you delete the array before accessing the data stored in it the behavior is undefined. It's only natural that it doesn't print anything. It could also print the expected result, that's one of the features of undefined behavior. Using Visual Studio or not, it's the same.
But if return arr[6] is above delete[] arr, would the memory be freed or this sentence be skipped?
Yes it would be skipped, or more accurately, all code after the return statement will not be executed. The memory will not be freed.
Or should I declare arr inside main() then free it in main()?
If the data should belong in the main's scope you should definitely declare it there, you can pass it to the function as an argument:
#include <cassert>
#include <iostream>
int fun(int* arr) {
assert(arr);
for (int i = 0; i < 10; i++) {
arr[i] = 5;
}
return arr[6];
}
int main() {
int* arr = new int[10];
std::cout << fun(arr);
delete[] arr;
return 0;
}

How can an declare an array in a function that returns an array in c++

// functions that converts a number into an array
int *initialiser(int number)
{
int array[20];
for (int i = 19; i >= 0; i--)
{
array[i] = number % 10;
number /= 10; // number = number/10
}
return array;
}
//I get this error
primaryAddSub.cpp: In function 'int* initialiser(int)':
primaryAddSub.cpp:21:9: warning: address of local variable 'array' returned [-Wreturn-local-addr]
int array[20];
^~~~~
I can use static int array[20]; but the function will return the same result each time I call it.
As the comment says, prefer to use a std::vector instead of an int*. An example of how this works would be:
std::vector<int> initialiser(int number)
{
std::vector<int> array;
// ... fill up array
return array;
}
If you absolutely want to return an int*, then as the error says, you are returning a pointer to a local variable. You need to allocate memory instead:
int *initialiser(int number)
{
int *array = new int[20];
// ... fill up array
return array;
}
Don't forget to delete this memory when you are done with it. Also, the caller really has no way to know how many elements are in the array, so they might read/write out of bounds.
In general this is error prone, so prefer the first version, then you don't have to worry about deleting anything, and are less likely to make out of bounds errors.

Array initialization functions

I was playing around with C++ and I stumbled upon this problem. I'm trying to initialize an array pointer on the heap, and it works inside the initialize(), where it outputs 69, but in the main(), it crashes with the error EXC_BAD_ACCESS.
#include <iostream>
void initialize(int* array, int size) {
array = new int[size];
// Testing
array[2] = 69;
std::cout << array[2] << std::endl; // Works fine
}
int main() {
int size = 3;
int* array;
// Initializing
initialize(array, size);
// Testing
std::cout << array[2] << std::endl; // Crash, EXC_BAD_ACCESS
// Cleanup
delete[] array;
array = nullptr;
return EXIT_SUCCESS;
}
Please help me understand the problem with this.
Yes, I know I should use std::vector but I want to understand why this doesn't work :)
When you pass array to the function, a copy of that pointer is made. When you assign new int[size]; to array, you assign it actually to the argument, which is the copy I was talking about. To really modify the array defined in main, use references. Change the definition of the function to
void initialize(int*& array, int size)
or return the pointer like1
int* initialize(int size)
and try it again.
I recommend the second method due to its higher expressiveness: something like
initialize(array, 3);
does not make clear if array is modified or not. OTOH,
int* array = initialize(3);
does.
1 as noted by #Jack in the comments to this answer
The reason why the program fails is because you want the memory to be allocated outside the initialize function and the function to operate on that memory.
Simply remove the new statement from your function so that it looks like this...
void initialize(int* array, int size) {
for (int i = 0; i < size; i++) {
cout << array[i] << " ";
}
}
... then, do your allocation in main and just before the function call...
int size = 3;
int* array = new int [size];
initialize(array, size);
Pass the address of the pointer to avoid the error message

Returning a pointer to an array in C++ [duplicate]

May I have any access to a local variable in a different function? If so, how?
void replaceNumberAndPrint(int array[3]) {
printf("%i\n", array[1]);
printf("%i\n", array[1]);
}
int * getArray() {
int myArray[3] = {4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
The output of the piece of code above:
65
4202656
What am I doing wrong? What does the "4202656" mean?
Do I have to copy the whole array in the replaceNumberAndPrint() function to be able to access it more than the first time?
myArray is a local variable and as thus the pointer is only valid until the end of its scope (which is in this case the containing function getArray) is left. If you access it later you get undefined behavior.
In practice what happens is that the call to printf overwrites the part of the stack used by myArray and it then contains some other data.
To fix your code you need to either declare the array in a scope that lives long enough (the main function in your example) or allocate it on the heap. If you allocate it on the heap you need to free it either manually, or in C++ using RAII.
One alternative I missed (probably even the best one here, provided the array is not too big) is to wrap your array into a struct and thus make it a value type. Then returning it creates a copy which survives the function return. See tp1's answer for details on this.
You can't access a local variable once it goes out of scope. This is what it means to be a local variable.
When you are accessing the array in the replaceNumberAndPrint function the result is undefined. The fact it appears to work first time is just a fortunate coincidence. Probably the memory location you are pointing to is unallocated on the stack and is still correctly set for the first call, but the call to printf then overwrites this by pushing values onto the stack during its operation which is why the second call to printf displays something different.
You need to store the array data on the heap and pass a pointer, or in a variable that remains in scope (e.g. a global or something scoped within the main function).
Try something like that. The way you do it "kills" myArray cause if it locally defined.
#include <stdio.h>
#include <stdlib.h>
void replaceNumberAndPrint(int * array) {
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n" , array[2]);
free(array);
}
int * getArray() {
int * myArray = malloc(sizeof(int) * 3);
myArray[0] = 4;
myArray[1] = 64;
myArray[2] = 23;
//{4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
More : http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/
Edit: As Comments correctly pointed out: A better way to do it would be that :
#include <stdio.h>
#include <stdlib.h>
void replaceNumberAndPrint(int * array) {
if(!array)
return;
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n" , array[2]);
}
int * createArray() {
int * myArray = malloc(sizeof(int) * 3);
if(!myArray)
return 0;
myArray[0] = 4;
myArray[1] = 64;
myArray[2] = 23;
return myArray;
}
int main() {
int * array = createArray();
if(array)
{
replaceNumberAndPrint(array);
free(array);
}
return 0;
}
myArray goes out of scope as soon as you leave getArray. You need to allocate space for it on the heap instead.
Your code invokes Undefined Behaviour because myArray goes out of scope as soon as getArray() returns and any attempt to use (dereference) the dangling pointer is UB.
Local variables go out of scope upon return, so you can't return a pointer to a local variable.
You need to allocate it dynamically (on the heap), using malloc or new. Example:
int *create_array(void) {
int *array = malloc(3 * sizeof(int));
assert(array != NULL);
array[0] = 4;
array[1] = 65;
array[2] = 23;
return array;
}
void destroy_array(int *array) {
free(array);
}
int main(int argc, char **argv) {
int *array = create_array();
for (size_t i = 0; i < 3; ++i)
printf("%d\n", array[i]);
destroy_array(array);
return 0;
}
Alternatively, you can declare the array as static, keeping in mind the semantics are different. Example:
int *get_array(void) {
static int array[] = { 4, 65, 23 };
return array;
}
int main(int argc, char **argv) {
int *array = get_array();
for (size_t i = 0; i < 3; ++i)
printf("%d\n", array[i]);
return 0;
}
If you don't know what static means, read this question & answer.
Right way to do this is as follows:
struct Arr {
int array[3];
};
Arr get_array() {
Arr a;
a.array[0] = 4;
a.array[1] = 65;
a.array[2] = 23;
return a;
}
int main(int argc, char **argv) {
Arr a = get_array();
for(size_t i=0; i<3; i++)
printf("%d\n", a.array[i]);
return 0;
}
To understand why you need to do this, you need to know how sizeof(array) works. C (and thus c++) tries hard to avoid copying the array, and you need the struct to go past that. Why copying is needed is because of scopes -- the get_array() function's scope disappears and every value still needed from that scope will need to be copied to calling scope.
C++ solution:
"May I have any access to a local variable in a different function? If so, how?"
The answer is no, not after the function has ended. Local variables are destroyed at that point.
In C++ the way to deal with returning arrays is to manage them in a container like a std::array (fixed size) or a std::vector (dynamic size).
Eg:
void replaceNumberAndPrint(const std::array<int, 3>& array) {
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n", array[2]);
}
std::array<int, 3> getArray() {
std::array<int, 3> myArray = {4, 65, 23};
return myArray;
}
In the second function the returned value is optimized by the compiler so you don't pay the price of actually copying the array.
In this code you have used pointer to local objects but when a function returns all local variables goes out of scope. If you will allocate memory (using malloc() function for allocation) then no data will be lost or overwrite.
int* getArray(int size) {
int *myArray = (int*)malloc(size*sizeof(int));
myArray[0] = 4;
myArray[1] = 65;
myArray[2] = 23;
return myArray;
}
int main() {
int i;
int *vector = getArray(3);
for(i=0;i<3;i++)
{
printf("%i\n",vector[i]);
}
getch();
return 0;
}
This code will print all the array elements and no overwritten will be happened.
Static ..or.. Global within your .c will do the trick ;)
However the entire time the program will occupy those 3 bytes BUT you avoid doing malloc on simple things like this (malloc recommended for big arrays)
On the other hand if the outside function modify the pointer, then the internal 'myArray' will be modified cause it points to it, that's it
int myArray[3];
int * getArray() {
myArray[0] = 4;
myArray[1] = 65;
myArray[2] = 23;
return myArray;
}

Array and Dynamically Allocated Memory [duplicate]

May I have any access to a local variable in a different function? If so, how?
void replaceNumberAndPrint(int array[3]) {
printf("%i\n", array[1]);
printf("%i\n", array[1]);
}
int * getArray() {
int myArray[3] = {4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
The output of the piece of code above:
65
4202656
What am I doing wrong? What does the "4202656" mean?
Do I have to copy the whole array in the replaceNumberAndPrint() function to be able to access it more than the first time?
myArray is a local variable and as thus the pointer is only valid until the end of its scope (which is in this case the containing function getArray) is left. If you access it later you get undefined behavior.
In practice what happens is that the call to printf overwrites the part of the stack used by myArray and it then contains some other data.
To fix your code you need to either declare the array in a scope that lives long enough (the main function in your example) or allocate it on the heap. If you allocate it on the heap you need to free it either manually, or in C++ using RAII.
One alternative I missed (probably even the best one here, provided the array is not too big) is to wrap your array into a struct and thus make it a value type. Then returning it creates a copy which survives the function return. See tp1's answer for details on this.
You can't access a local variable once it goes out of scope. This is what it means to be a local variable.
When you are accessing the array in the replaceNumberAndPrint function the result is undefined. The fact it appears to work first time is just a fortunate coincidence. Probably the memory location you are pointing to is unallocated on the stack and is still correctly set for the first call, but the call to printf then overwrites this by pushing values onto the stack during its operation which is why the second call to printf displays something different.
You need to store the array data on the heap and pass a pointer, or in a variable that remains in scope (e.g. a global or something scoped within the main function).
Try something like that. The way you do it "kills" myArray cause if it locally defined.
#include <stdio.h>
#include <stdlib.h>
void replaceNumberAndPrint(int * array) {
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n" , array[2]);
free(array);
}
int * getArray() {
int * myArray = malloc(sizeof(int) * 3);
myArray[0] = 4;
myArray[1] = 64;
myArray[2] = 23;
//{4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
More : http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/
Edit: As Comments correctly pointed out: A better way to do it would be that :
#include <stdio.h>
#include <stdlib.h>
void replaceNumberAndPrint(int * array) {
if(!array)
return;
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n" , array[2]);
}
int * createArray() {
int * myArray = malloc(sizeof(int) * 3);
if(!myArray)
return 0;
myArray[0] = 4;
myArray[1] = 64;
myArray[2] = 23;
return myArray;
}
int main() {
int * array = createArray();
if(array)
{
replaceNumberAndPrint(array);
free(array);
}
return 0;
}
myArray goes out of scope as soon as you leave getArray. You need to allocate space for it on the heap instead.
Your code invokes Undefined Behaviour because myArray goes out of scope as soon as getArray() returns and any attempt to use (dereference) the dangling pointer is UB.
Local variables go out of scope upon return, so you can't return a pointer to a local variable.
You need to allocate it dynamically (on the heap), using malloc or new. Example:
int *create_array(void) {
int *array = malloc(3 * sizeof(int));
assert(array != NULL);
array[0] = 4;
array[1] = 65;
array[2] = 23;
return array;
}
void destroy_array(int *array) {
free(array);
}
int main(int argc, char **argv) {
int *array = create_array();
for (size_t i = 0; i < 3; ++i)
printf("%d\n", array[i]);
destroy_array(array);
return 0;
}
Alternatively, you can declare the array as static, keeping in mind the semantics are different. Example:
int *get_array(void) {
static int array[] = { 4, 65, 23 };
return array;
}
int main(int argc, char **argv) {
int *array = get_array();
for (size_t i = 0; i < 3; ++i)
printf("%d\n", array[i]);
return 0;
}
If you don't know what static means, read this question & answer.
Right way to do this is as follows:
struct Arr {
int array[3];
};
Arr get_array() {
Arr a;
a.array[0] = 4;
a.array[1] = 65;
a.array[2] = 23;
return a;
}
int main(int argc, char **argv) {
Arr a = get_array();
for(size_t i=0; i<3; i++)
printf("%d\n", a.array[i]);
return 0;
}
To understand why you need to do this, you need to know how sizeof(array) works. C (and thus c++) tries hard to avoid copying the array, and you need the struct to go past that. Why copying is needed is because of scopes -- the get_array() function's scope disappears and every value still needed from that scope will need to be copied to calling scope.
C++ solution:
"May I have any access to a local variable in a different function? If so, how?"
The answer is no, not after the function has ended. Local variables are destroyed at that point.
In C++ the way to deal with returning arrays is to manage them in a container like a std::array (fixed size) or a std::vector (dynamic size).
Eg:
void replaceNumberAndPrint(const std::array<int, 3>& array) {
printf("%i\n", array[0]);
printf("%i\n", array[1]);
printf("%i\n", array[2]);
}
std::array<int, 3> getArray() {
std::array<int, 3> myArray = {4, 65, 23};
return myArray;
}
In the second function the returned value is optimized by the compiler so you don't pay the price of actually copying the array.
In this code you have used pointer to local objects but when a function returns all local variables goes out of scope. If you will allocate memory (using malloc() function for allocation) then no data will be lost or overwrite.
int* getArray(int size) {
int *myArray = (int*)malloc(size*sizeof(int));
myArray[0] = 4;
myArray[1] = 65;
myArray[2] = 23;
return myArray;
}
int main() {
int i;
int *vector = getArray(3);
for(i=0;i<3;i++)
{
printf("%i\n",vector[i]);
}
getch();
return 0;
}
This code will print all the array elements and no overwritten will be happened.
Static ..or.. Global within your .c will do the trick ;)
However the entire time the program will occupy those 3 bytes BUT you avoid doing malloc on simple things like this (malloc recommended for big arrays)
On the other hand if the outside function modify the pointer, then the internal 'myArray' will be modified cause it points to it, that's it
int myArray[3];
int * getArray() {
myArray[0] = 4;
myArray[1] = 65;
myArray[2] = 23;
return myArray;
}