Reading pointers twice is giving garbage values - c++

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.

Related

C++ pointer/for-loop confusion

I'm trying to write a program that reads values from cin using a pointer, and then outputs the values alongside their position in the array. I can't figure out why printNumbers1 works but printNumbers2 doesn't. Here is the program (relevant code near the bottom):
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *readNumbers(int n)
{
int a[n];
int *numbers;
numbers = &a[0];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}
When I run the program, it works as intended for printNumbers1 but outputs a combination of seemingly random numbers and 0s for printNumbers2. I feel like the two printNumbers functions should should function identically, but they don't. What am I missing?
This happens because of a combination of two things:
C++ does not allow variable-length arrays - this is a popular extension, but the declaration int a[n] is not standard.
You cannot return a pointer to local variable from a function - pointer numbers inside readNumbers points to a, a local variable. You can use this pointer inside the function, but outside of the function it becomes invalid, because a goes out of scope.
Using an out-of-scope variable causes undefined behavior. This Q&A provides a very good explanation of what is happening, and why it may look like the program is working fine.
If you want to use built-in pointers, remove int a[n], and change the declaration of numbers as follows:
int *numbers = new int[n];
You also need to add
delete[] numbers;
before return 0 line to avoid memory leaks.
I am assuming that you wrote this code as part of a learning exercise. In general, though, a better approach in C++ is to use std::vector<int>, which hides pointer operations from your code, and deals with resource management for you.
readNumbers returns a pointer to a variable with automatic storage duration.
The behaviour on dereferencing that pointer is undefined.
Use a std::vector instead. Rely on return value optimisation to obviate any superfluous value copies being taken.
Here you have created the array a[n] inside the function, so it is a local variable, Hence this array may or may not be deleted after the scope of the function ends.Never use the address of a local variable outside the funcrtion. This code is working:
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *numbers;
int *readNumbers(int n)
{
numbers = new int[n];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}

arrays using pointers in c++: segmentation fault when accessing the returned array

I'm new to C++ and I'm trying to build a 3 dimensional array using a pointer to a pointer to a pointer. I am sure there are more efficient ways in doing so, but I am trying to understand pointers at the moment.
As example code, I originally had the following piece, which worked fine, allocating, initializing, and releasing the memory.
void builder(int aSize1, int aSize2, int aSize3)
{
int i1, i2, i3;
int ***frequencies;
cout << "allocation started ..." << endl;
frequencies = new int** [aSize1+1];
for (i1=0; i1<=aSize1; i1++){
frequencies[i1] = new int*[aSize2+1];
for (i2 = 0; i2 <= aSize2; i2++)
{
frequencies[i1][i2] = new int [aSize3 + 1];
}
}
cout << "allocation done" << endl;
cout << " " << endl;
cout << "before initialization" << endl;
for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
for(i3 = 0; i3 <= aSize3; i3++)
{
frequencies[i1][i2][i3]= (i1 * i2) % 10;
}
}
}
cout << "after initialization" << endl;
cout << " " << endl;
/* the "destroyer" part */
cout << "deleting ..." << endl;
for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
delete [] frequencies[i1][i2];
}
}
for (i1=0; i1<aSize1; i1++){
delete [] frequencies[i1];
}
delete [] frequencies;
cout << "deleting done" << endl;
}
I wanted to up the ante by splitting the code above into several parts, so that I could use the initialized array in the main() function of my program (just to see if I can access them there as well). So, I ended up doing the following
The header file:
void builder(int aSize1, int aSize2, int aSize3, int*** frequencies)
{
int i1, i2, i3;
//int ***frequencies;
cout << "allocation started ..." << endl;
frequencies = new int** [aSize1+1];
for (i1=0; i1<=aSize1; i1++){
frequencies[i1] = new int*[aSize2+1];
for (i2 = 0; i2 <= aSize2; i2++)
{
frequencies[i1][i2] = new int [aSize3 + 1];
}
}
cout << "allocation done" << endl;
cout << " " << endl;
cout << "before initialization" << endl;
for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
for(i3 = 0; i3 <= aSize3; i3++)
{
frequencies[i1][i2][i3]= (i1 * i2) % 10;
}
}
cout << **(frequencies[i1]+2) << endl;
}
cout << "after initialization" << endl;
cout << " " << endl;
}
void destroyer( int aSize1, int aSize2, int aSize3, int*** frequencies )
{
int i1, i2;
cout << "deleting ..." << endl;
for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
delete [] frequencies[i1][i2];
}
}
for (i1=0; i1<aSize1; i1++){
delete [] frequencies[i1];
}
delete [] frequencies;
cout << "deleting done" << endl;
}
and my main() where I try to access the 3d array in a fruitless effort.
int main()
{
int aSize1 = 10;
int aSize2 = 10;
int aSize3 = 10;
int*** freq;
builder(aSize1, aSize2, aSize3, freq);
cout << "builder finished" << endl;
cout << **(freq[1]+2) << endl;
destroyer( aSize1, aSize2, aSize3, freq);
}
When I compile this, the "builder" function runs fine, but I get a segmentation fault whenever I try to access the 3d array in the main function. I would expect this to work because I have read it in my book that if something is passed by reference using a pointer to a function, the function would have the power to manipulate it. Also, I expected that I would need to dereference the 3d array 3 times (i.e. ***freq) in order to correctly access the elements, but the compiler gets mad at me for trying to do so and blurts out
myBuilder.cpp:42:17: error: indirection requires pointer operand ('int' invalid)
cout << ***(frequencies[i1]+1) << endl;
I know this is a newb question, but any help will be appreciated!
The frequencies pointer in builder and destroyer is a copy of the freq pointer in main. So setting it in builder does not change the (uninitialized) pointer in main. You want a reference to pointer instead:
void builder(int aSize1, int aSize2, int aSize3, int***& frequencies);
And for your levels of indirection, note that if freq is an int***, then freq[1] is an int**.
In code when you call builder(aSize1, aSize2, aSize3, freq); from main(), you are passing int ***frequencies(that contains garbage value since its inception) and want this triple pointer to be updated within builder function call.
The builder function allocates memory and updates a copy of ***frequecny passed as parameter in builder function call in below code line
frequencies = new int** [aSize1+1];
Thus, it is a call by value for frequency pointer, which is not returned updated in main() after completion of call to builder. It still contains garbage address in it that gets accessed to cause you segmentation fault.
You need to pass the address of frequencies pointer like &frequencies in builder call and make the changes accordingly in builder function.

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;

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.