C++ returning pointer - c++

#include <iostream>
using namespace std;
int* createArray();
int main() {
int *arr = createArray();
cout << "Main: " << arr << endl;
arr[0] = 0;
arr[1] = 1;
cout << arr[0] << endl;
cout << arr[1] << endl;
}
int* createArray() {
int arr[2];
cout << "createArray()1: " << arr << endl;
return arr;
}
I don't understand why if I only call this statement
cout << arr[0] << endl;
or
cout << arr[1] << endl;
can show a correct value.
But if I call both statement, it will show
createArray()1: 00AFFAF4
Main: 00AFFAF4
0
11533068 //Don't show 1

The pointer returned by createArray points to a non-existing object. The local array was destroyed when the function returned. When you dereference the dangling pointer in main, the behaviour of your program is undefined.
Solution: Don't ever return pointers or references to local variables. In this case, you could for example return a copy of the array. You cannot return a raw array by value, but you can return a wrapper structure like std::array<int, 2>.

You are returning a pointer to local variable which is destroyed at function block end.
But beware, when you use new operator, you need to use delete somewhere else (atleast without of use of smart pointers).
Solution:
int* createArray() {
int* arr = new int[2];
// your code
return arr;
}

Related

Array of pointers unexplained behavior (with shallow copy) c++

This is a behavior with array of pointers in C++ (GNU GCC compiler) that I can't find an explanation for, hopefully someone can clear the confusion.
I'm creating an array of pointers (arr_ptr), The pointers are pointing to valid data, then I create another array of pointers (arrcopy), I do -what I think- a shallow copy (arrcopy = arr_ptr), and I get the data as expected...so far so good.
The part I am not understanding is, after I delete arr_ptr, shouldn't arrcopy still be pointing to my valid data? Why this is not happening?
Thank you.
int main()
{
int a = 1; int b=2; int c=3;
int* ap = &a; int* bp = &b; int* cp = &c;
// Array of pointers
int** arr_ptr = new int*[3];
arr_ptr[0] = ap;
arr_ptr[1] = bp;
arr_ptr[2] = cp;
//shallow copy
int** arrcopy = arr_ptr;
cout << "Values: " << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << "Addresses: " << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
a++;
cout << "After Incrementing a:" << endl;
cout << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
*(arr_ptr[0]) = 5;
cout << "After updating a value to 5:" << endl;
cout << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
//so far so good - works as expected
//deleting arr_ptr
delete[] arr_ptr;
// Why?: shouldn't arrcopy still be pointing to A
cout << "Values: " << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl; //The result I am expecting here is: unknown_value 5
cout << "Addresses: " << arr_ptr[0] << " " << arrcopy[0];
cout << endl;
return 0;
}
After Shallow copy of arr_ptr to arrcopy (arrcopy = arr_ptr)
After deleting arr_ptr, shouldn't arrcopy still be pointing to the memory locations of a,b,c data values?!
You do not have 2 arrays after the assignment you have 2 pointers to the same array:
arr_ptr -------->|ptr0|ptr1|ptr2|ptr3... (allocated memory)
arr_cpy = arr_ptr; // copy only the pointer
Now both pointers point to the same allocated memory:
arr_ptr -------->|ptr0|ptr1|ptr2|ptr3...
^
arr_cpy -----------|
delete[] arr_ptr; // invalidate the memory that both pointers point to
This gives:
arr_ptr -------->|xxx0|xxx1|xxx2|xxx3... (invalid memory)
^
arr_cpy -----------|
It doesn't matter which pointer you call delete[] on, they both point to the same block of allocated memory so after the call they both point to the same block of invalidated memory.
What you need to do is copy the whole array:
int** arr_cpy = new int*[3];
std::copy(arr_ptr, arr_ptr + 3, arr_cpy); // copy the pointers to the new array
Or much better use a std::vector:
int main()
{
int a = 1; int b=2; int c=3;
int* ap = &a; int* bp = &b; int* cp = &c;
// Array of pointers
std::vector<int*> arr_ptr{3};
arr_ptr[0] = ap;
arr_ptr[1] = bp;
arr_ptr[2] = cp;
//shallow copy
std::vector<int*> arr_cpy = arr_ptr; // copy the whole vector
// ... etc.
No need for delete[], memory is deallocated automatically when your vector goes out of scope.
Neither arr_ptr nor arrcopy is an array. Both are just pointers.
A C++ pointer is a little overloaded. It can point to a single object or to an array of objects.
In your case arr_ptr is initialized with the address of the array that you allocated in the dynamic memory. But it could as well be initialized with an address of a single object on the stack:
int i = 0;
int** arr_ptr = &i;
By copying the value of that pointer into another pointer of the same type you simply have two pointers referring to the same memory location:
// array in the heap
[xxxxxxxxxxxxxxxxxxxxxxx]
^
/ \
/ \
/ \
arr_ptr arrcopy

How can I assign a different address to an array?

I want to pass an array to a function, then point that array variable to a new address altogether within said function.
I realize that arrays behave as pointers to the adress of their first element when passed to a function, so why the heck won't the address change for my array variable in main?
#include <iostream>
using namespace std;
void passArrayByReference(int * array) { //passing array as. pointer should let us modify it's address, correct?
cout << "Address of array in function is: " << array << endl;
int * localArray = new int [2];
//put some dummy values in our localArray
localArray[0] = 9;
localArray[1] = 9;
array = localArray;
cout << "Address of array in function is now: " << array << endl;
}
int main()
{
int * array = new int [2];
int totalElements = 2;
//put some initial values into our dynamic 1D array
array[0] = 0;
array[1] = 1;
//print our initial values
for(int i = 0; i < totalElements; i++)
cout << array[i] << endl;
cout << "Address of array in main: " << array << endl;
passArrayByReference(array);
cout << "Address of array in main: " << array << endl;
return 0;
}
You are on the right track, but you just need to include the '&' symbol in your function header. The '&' symbol is used to pass an argument by reference, as opposed to by value.
In this case you are passing the address to the first element of your array by reference, meaning that you can modify that address in the function, and the changes will be reflected in your main function.
#include <iostream>
using namespace std;
void passArrayByReference(int * &array) {
cout << "Address of array in function is: " << array << endl;
int * localArray = new int [2];
//put some dummy values in our localArray
localArray[0] = 9;
localArray[1] = 9;
array = localArray;
cout << "Address of array in function is now: " << array << endl;
}
int main()
{
int * array = new int [2];
int totalElements = 2;
//put some initial values into our dynamic 1D array
array[0] = 0;
array[1] = 1;
//print our initial values
for(int i = 0; i < totalElements; i++)
cout << array[i] << endl;
cout << "Address of array in main is: " << array << endl;
passArrayByReference(array);
cout << "Address of array in main is now: " << array << endl;
//now print the values of our 'new' array
cout << "The values of array are now:" << endl;
for(int i = 0; i < totalElements; i++)
cout << array[i] << endl;
return 0;
}
First, you have to pass pointer by pointer or reference to make persistent change to it - that is change original pointer and not only copy of it in function body:
void passArrayByReference(int *&array) {
//...
array = new_address;
std::cout << "Address of array in function is now: " << array << std::endl;
}
// and here it is the same
And second you should assign valid address new_address and take care of memory that array referenced just before it entered the function, to avoid memory leak.
Pointers are variables as well.
That's why you need to pass array as a reference to passArrayByReference so you don't just modify the copy of it.
void passArrayByReference(int *&array)

C++ How would the calling of these functions change if i change the parameter argument from an int* to int [duplicate]

This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;

Reading pointers twice is giving garbage values

I want to return an array created in a local function through pointers to the main function. My code is below. The array is returned and I am able to access each element by element once only. The next time it is giving garbage values. What is Wrong?
void DoWork(int** ppOut , int& nSize)
{
int m[5];
for(int i = 0 ; i < 5 ; i++)
{
m[i] = i;
}
nSize = 5;
cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;
cout << m[3] << endl;
cout << m[4] << endl;
*ppOut = &m[0];
//delete [] m;
}
void main()
{
int nSize = -1;
int i;
int* f = NULL;
DoWork(&f , nSize);
cout << f[3] << endl;
cout << f[0] << endl;
cout << f[2] << endl;
cout << f[3] << endl;
cout << f[4] << endl;
_getch();
}
Output is:-- 0 1 2 3 4 from local function.
But in main 3 and rest are grabage values
The Problem:
The array m is a local array which does not exist beyond the lifetime of the function DoWork(). When you do so what you end up with is Undefined Behavior, which basically means that you can see any observable behavior because the program ceases to be a C++ standard approved program and so it can show(literally) any behavior.
The Solution:
You will need to extend the lifetime of m so that it is still valid even after the function returns. There are number of ways to do this:
Create an array before the function & pass a pointer to it to the function.
Create a static array inside the function.
Use dynamic memory for the array in function (do remember to release it after usage)
Use global array which can be poulapted inside the function.
Each has own pros and cons and its more of horses for courses.
On a side note, void main() is not the standard specified prototype for main() it should return an int:
int main()
The main function in a C++ program should be int main
Returning a pointer to a local variable exhibits undefined behavior.

Having trouble using an array that is returned by a function in C++

I have a function that generates values in an array and returns a pointer to that array. Here's the MWE code:
int *f(size_t s)
{
int *ret=new int[s];
for(size_t a=0;a<s;a++)
{
ret[a]=a;
cout << ret[a] << endl;
}
return ret;
}
note that I have a cout line in for for loop to prove to myself that the array is being populated properly.
Now, here's my problem. I can't find the correct method of using the returned array. Here's what I've been doing:
int main (void)
{
int ary_siz = 10;
int ary[ary_siz];
*ary = *f(ary_siz);
cout << ary[0] << endl;
cout << ary[2] << endl;
cout << ary[3] << endl;
}
The first element in ary seems to be right. The others (ary[1],ary[2]...) are not. Can anyone tell me what I'm doing wrong?
int main (void)
{
int ary_siz = 10;
int *ary = f(ary_siz);
cout << ary[0] << endl;
cout << ary[2] << endl;
cout << ary[3] << endl;
delete [] ary;
}
The assignment
*ary = *f(ary_siz);
copies a single element. Use
int main (void)
{
int ary_siz = 10;
int *ary = f(ary_siz);
delete[] ary;
}
fixing the memory leak as well
You allocate an array in the function and you just assign its first element to the first element of your stack-allocated array, instead of just using the returned array.
you should do something like that:
int main (void)
{
int ary_siz = 10;
int *ary;
ary = f(ary_siz);
cout << ary[0] << endl;
cout << ary[2] << endl;
cout << ary[3] << endl;
delete[] ary // don't forget to release the memory
return 0; // You should return something in the main function
}
Moreover, in C++ you should use vectors instead of "bare-metal" arrays whenever possible.
How about this?
int *ary = f(ary_siz);
The you can just use the [] operator as you do in the couts.