When I return pointer from the function, its value can be accessed individually. But when a loop is used to ouput the value of that pointer variable, wrong value is shown. Where I am making mistake, can't figure it out.
#include <iostream>
#include <conio.h>
int *cal(int *, int*);
using namespace std;
int main()
{
int a[]={5,6,7,8,9};
int b[]={0,3,5,2,1};
int *c;
c=cal(a,b);
//Wrong outpur here
/*for(int i=0;i<5;i++)
{
cout<<*(c+i);
}*/
//Correct output here
cout<<*(c+0);
cout<<*(c+1);
cout<<*(c+2);
cout<<*(c+3);
cout<<*(c+4);
return 0;
}
int *cal(int *d, int *e)
{
int k[5];
for(int j=0;j<5;j++)
{
*(k+j)=*(d+j)-*(e+j);
}
return k;
}
You are returning a pointer to a local variable.
k is created on the stack. When cal() exits the stack is unwound and that memory is free'd. Referencing that memory afterwards leads to undefined behaviour (as explained beautifully here: https://stackoverflow.com/a/6445794/78845).
Your C++ compiler should warn you about this and you should heed these warnings.
For what it's worth, here is how I'd implement this in C++:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
int main()
{
int a[] = {5, 6, 7, 8, 9};
int b[] = {0, 3, 5, 2, 1};
int c[5];
std::transform (a, a + 5, b, c, std::minus<int>());
std::copy(c, c + 5, std::ostream_iterator<int>(std::cout, ", "));
}
See it run!
The int k[5] array is created on the stack. So it gets destroyed when it goes out of scope by returning from cal. You could use a third parameter as an output array:
void cal(int *d, int *e, int* k)
{
for(int j=0;j<5;j++)
{
*(k+j)=*(d+j)-*(e+j);
}
}
call cal like this:
int a[]={5,6,7,8,9};
int b[]={0,3,5,2,1};
int c[5];
cal (a, b, c); // after returning from cal, c will be populated with desired values
As others have pointed out, you're returning a pointer to a local
variable, which is undefined behavior. The real problem, however, is
that you need to return an array, and C style arrays are broken.
Replace your arrays with std::vector<int>, forget about the pointers
(because you're dealing with values), and the code will work.
Related
What is the difference between passing by reference and passing by address (using pointer) notation?
Is int arr[] = int* arr ??
I have added three samples of codes, I think the first 2 samples are passing by address and the last one is passing by reference.
void fun(int *arr, unsigned int n)
{
int i;
for (i=0; i<n; i++)
printf("%d ", arr[i]);
}
// Driver program
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned int n = sizeof(arr)/sizeof(arr[0]);
fun(arr, n);
return 0;
}
#include <stdio.h>
void fun(int arr[], unsigned int n)
{
int i;
for (i=0; i<n; i++)
printf("%d ", arr[i]);
}
// Driver program
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned int n = sizeof(arr)/sizeof(arr[0]);
fun(arr, n);
return 0;
}
void scale_number(int (&num)[5]);
int main() {
int number[5]={1,2,3,4,5};
scale_number(number);
cout << number << endl;
return 0;
}
void scale_number(int (&num)[5]) {
for(int i=0;i<5;i++)
num[i]=0;
}
is int arr[] = int* arr ??
In short:
In a function parameter declaration: Yes.
Otherwise: No.
Explanation:
int[] is an array of unknown bound of integers.
int* is a pointer to an integer.
A function parameter is never an array. Any function parameter declared to be an array will be adjusted to be a pointer to element of such array. Therefore int[] is adjusted to be int*, but only when it is a function parameter.
i think first 2 samples are passing by address and last one is passing by reference.
Yes. In first two example you pass pointer to an integer, and in the last example you pass a reference to an integer. There is no array in the last example however.
The main differences between pointer and reference are:
Pointers are objects. References are not objects.
Objects have storage (although sometimes it may be optimised away if not observed). It is unspecified whether references have storage - sometimes they do, other times they do not.
There can be pointers-to- and arrays of objects. There cannot be pointers-to- nor arrays of references.
Indirection through pointer is explicit (using one of the indirection operators). Indirection through reference is implicit (operations on a reference are performed on the referred object).
A pointer can be default initialised, and it can point to null. Reference cannot (but reference can become invalid, just like a pointer can).
The questions I'm asking are very basic, but I'm trying to understand the behaviour of pointers in C++ by doing exercises in the compiler. So, for example, I start by declaring an int pointer *p and trying to ascribe it some values and print it:
#include <iostream>
using namespace std;
int *p, i;
int main(){
i=5;
p=&i;
cout<<*p<<endl;
return 0;
}
This is very clear and easy, right? But while I'm wondering why the C++ syntax works this way, I test another way of assigning a value to a pointer:
#include <iostream>
using namespace std;
int *p, i;
int main(){
i=5;
p=&i;
*p=3;
cout<<*p<<endl;
return 0;
}
Obviously, the result is different now. The question is, why this wouldn't work:
#include <iostream>
using namespace std;
int *p, i;
int main(){
*p=3;
i=5;
p=&i;
cout<<*p<<endl;
return 0;
}
Why do I have to dereference the pointer first before assigning it a value, but direct assignment would not work without dereferencing?
Also, if in the second example I wrote I added another assignment:
int main(){
i=5;
p=&i;
*p=3;
*p=6;
cout<<*p<<endl;
return 0;
}
This would not change the value stored at *p (it would still be 3). I don't simply want to learn by memorising this pointer behaviour, I'm interested in understanding why it works this way. Thanks.
#include <iostream>
using namespace std;
int *p, i;
int main(){
*p=3;
i=5;
p=&i;
cout<<*p<<endl;
return 0;
}
This doesn't work because you are trying to assign a value to the integer that p points to. That's what this line does:
*p = 3;
That means, "store the value 3 at the location which p points at". But p doesn't point at anything, because you didn't assign it to point to anything until two lines later.
p = &i;
That means, "assign the address of i to be the value of p". Or, in other words, "store the address of i in p". p needs to point to something, before you can assign to the thing p points to. Otherwise you have undefined behavior.
On the last section:
int main(){
i=5;
p=&i;
*p=3;
*p=6;
cout<<*p<<endl;
return 0;
}
You say this: "This would not change the value stored at *p (it would still be 3)." -- I'm not sure why you say that. Yes, it would change the value stored at *p (which is the value of i). It changes it to 6.
The question is, why this wouldn't work:
int *p, i;
int main(){
*p=3;
here you attempt to dereference p and write something, but since p is uninitialized here (it can be 0, for example), you are trying to write to memory that you didn't allocate, thus this is a segmentation fault.
Also, if in the second example I wrote I added another assignment: [...] This would not change the value stored at *p (it would still be 3).
Actually, it would. Why would you think otherwise?
I'm interested in understanding why it works this way.
You're on the right track, just continue reading (e.g. this thread) and experimenting!
What is difference between "passed by value-result", "passed by reference" and "passed by name"?
I have a program in C++:
#include <stdio.h>
#include <iostream>
using namespace std;
void swap(int a, int b) {
int temp;
temp = a;
a = b;
b = temp;
}
int main() {
int value = 2, list[5] = {1, 3, 5, 7, 9};
swap(value, list[0]);
swap(list[0], list[1]);
swap(value, list[value]);
return 0;
}
And this is the solution after call swap : http://imgur.com/1HkCAnm
I don't know the difference between them. Please help me explain it.
C++ uses call by value by default, and can use call by reference if the argument is correctly decorated. (Pointer arguments pass the value of the pointer.)
If you specify a reference argument (int& a) in the updated sample below), your swap function will work.
Call by value-result isn't supported by C++; it works by passing the value in at the start of the function and copying the value out at the end of the function.
Call by name is just weird. Instead of passing values, it passes bits of code (aka thunks) that evaluate the variable (in the calling scope). Array references are notorious for not being evaluated as one would expect using call by name.
void swap(int& a, int& b) {
int temp;
temp = a;
a = b;
b = temp;
}
#include <iostream>
using namespace std;
int main ()
{
int **a;
int b[5] = {3,4,5,6,1};
*a=b;
cout << *((*a)+0) << endl;
return 0;
}
According to my understanding *((*a)+0) is equivalent to (*a)[0]. Am I wrong? How can I make the above code print the first element of the array?
And why does this code work?
#include <iostream>
using namespace std;
int main ()
{
int *a;
int b[5] = {3,4,5,6,1};
a=b;
cout << *(a+0) << endl;
return 0;
}
When I replace a with *a everywhere, why is it wrong?
You access an uninitialized pointer in
*a=b;
At this point a points to a random location, and as is the rule with undefined behavior you can't predict what will happen. For you it seems to be a location that you can't write to, and so you get a crash.
The second variant works because then you make a point to b, you don't write to an uninitialized pointer, you actually initialize the pointer with the location of the first item in b.
I am new to C/C++ and I had a question about dynamically allocating arrays. Can you not make a global dynamically allocated array? What if I wanted arr to be used by multiple functions? Would I have to pass arr to every function? Basically I guess I am still confused on the concept of dynamically allocated arrays and how I could create an array that can be used by a few functions.
The following produces : error: ‘arr’ does not name a type, but I am not sure exactly why.
#include <iostream>
using namespace std;
int * arr = NULL;
arr = new int [10];
int main() {
arr[0] = 1;
return 0;
}
That's invalid for the same reason that this is invalid
#include <iostream>
using namespace std;
int a = 0;
a = 2;
int main() {
}
You can't run statements outside of a function, only initializers. As a result, this works:
#include <iostream>
using namespace std;
int *arr = new int[10];
int main() {
arr[0] = 1;
return 0;
}
You don't even have to make the array dynamic, you can just put the array in static memory outside main, and it will live as long as the program.
#include <iostream>
int arr[10];
int main() {
arr[0] = 1;
return 0;
}
int* arr = new int[10];
or (since you are allocate a constant size array):
int arr[10];
You can't have "code" outside of a function. You need to put the call to new inside a function - you only have one in your code: main, but as long as it is a function that is executed before you access the array, it's fine.
You can also, as the comment says, do int *arr = new int[10]; - as long as it's part of the initialization, and not on a separate line.