my function get_num returns a variable of long int.
I want to write the next operator:
long int& operator [] (long int i) {
long int a = get_num(i);
int& b = a;
return b;
}
but I got the next error:
error C2440: 'initializing' : cannot convert from 'long' to 'int &'
error C2440: 'return' : cannot convert from 'int' to 'long &'
how can I fix it without changing the function of get_num?
any help appreciated!
I have a class:
class B {
B* next;
long int nom;
long int denom;
public:
long int get_nom() {return nom; }
long int get_denom() {return denom; }
};
class List {
B* head;
public:
long int& operator [] (long int desired_denom) {
// here I search the node that containts the denom that is equal to desired_denom
// and insert it to tmp (it's a pointer to B).
long int a1 = tmp->get_nom()
long int& a2 = a1;
return a2;
}
};
now in the main, I want to do:
int main() {
A a; // assume that it creates the list of B and put values in each node (each B)
// here I want to do:
a[2] = 3; // it should search the node that his denom is equal to 2, and puts 3 instead of his nom
return 0;
}
for example:
if my list is:
(nom=5, denom=6)->(nom=1,denom=8)->(nom=4, denom=2)->NULL
the line a[2]=3 searches the node that his denom is 2 (it's the third node) and set his nom to 3.
so after this line, my list will be:
(nom=5, denom=6)->(nom=1,denom=8)->(nom=3, denom=2)->NULL
Currently in your code there isn't a way to modify the nodes the way you want to. get_nom will have to be changed to return a reference before it can behave the way you would like. Right now you can only make copy of the values in each node of the linked list.
Assuming tmp is set correctly you can return the reference returned by get_nom
long int& operator [] (long int i) {
//Get tmp here probably by list traversal
return tmp->get_nom(i);
}
And then the implementation of get_nom. It is important to note that nom must be a value with a lifespan long enough to be of use as explained below. Returning nom which is private to the class and therefor will not fall out of scope when the function returns should work.
long int& get_nom() {return nom; }
get_nom must return long int& for this to work. There is an important difference between returning long int and long int&. When the return type is long int a copy of the value you are returning is made and passed to the caller. When you return long int& or in other words return a long int by reference, the reference points to the location in memory where the value is stored. This reference allows you to change the value of a long int while it is still stored in the middle of an array or whatever data type you are using.
Another important side effect of this is that if you return a reference to a local variable, when the variable falls out of scope, the value will no longer exist in memory. I haven't actually tried compiling and running this so I'm not sure if the compiler will get mad or what exactly the result will be, but I know it won't be good:
long int& operator [] (long int i) {
long int a = i + 5; //arbitrary change
return a;
}
In this case you are returning a reference to the location of a, but because a falls out of scope after the function finishes executing, the reference no longer points to anything at all. The variable you are returning a reference to must still exist after the function exits.
The compile error is for this line
int& b = a;
^^^^
It should be
long int& b = a;
^^^^^^^^
And, as friends have said in the comments, returning a reference to a local variable leads to a undefined-behavior because that referenced variable will be destroyed after exiting the function.
Blindly asnwering, you might need return a reference to the get_num, if get_num is returning a reference correctly.
return get_num(i);
Related
I'm trying to understand pointer return types from functions.
The following example produces a type conversion error.
#include <iostream>
using namespace std;
int* abc(int* y)
{
int x=y;
int *z = &x;
x++;
return z;
}
int main()
{
int *a = abc(100);
int b = *a;
cout << a <<endl;
cout << b <<endl;
return 0;
}
The error message is:-
In function 'int* abc(int*)': 6:11: error: invalid conversion from 'int*' to 'int' [-fpermissive]
In function 'int main()': 14:19: error: invalid conversion from 'int' to 'int*' [-fpermissive]
4:6: note: initializing argument 1 of 'int* abc(int*)'
How to resolve the above error and also what is the difference between the following function forms and their appropriate calling syntax,
int* function()
int * function()
int *function()
The argument type in
int* abc(int* y)
is int*. When you call the function,
int *a = abc(100);
you are passing 100, an int. It is not a pointer to an int.
You can fix the problem by using:
Option 1
Change the argument type.
int* abc(int y) { ... }
Option 2
Change the way you call the function.
int x = 100;
int *a = abc(&x);
If you follow this option,
The line
int x=y;
needs to be modified. Type of y is int*, not int. You'll have to change the line to:
int x=*y;
Problem
You are returning the address of a local variable from the function. Dereferencing that address in the calling function is undefined behavior.
When you return an address from a function and the calling function dereferences that address, the address needs to be valid in the calling function. One way to do that is to allocate memory from heap using malloc.
int* abc(int* y)
{
int* x = malloc(sizeof(int));
*x = (*y + 1);
return x;
}
When you do that, you'll have to remember to call free in the calling function.
int x = 100;
int *a = abc(&x);
// Use a
// Deallocate memory
free(a);
The problem is not your return type. Your problem is on this line:
int x=y;
Here y is a pointer and you're trying to assign it to x which is an int.
You're also passing a literal 100 which is an int to the abc function which takes a pointer as an argument.
Finally, there is no difference between the types of the 3 functions you give. Whitespace is insignificant in this context.
Your first two statements in both functions are incorrect. 100 is not a pointer when main calls abc, and blindly assigning y to x won't work because the former is an int and the latter is an int pointer.
#include <iostream>
using namespace std;
int func(int arg0, int *arg1, int *arg2);
int main() {
int *b;
int z;
int a[10];
z = func(*a[0], &a[z], b+a[4]);
}
The following code above gives me an error "invalid type argument of unary '*' (have 'int')". I know that * when used in a declaration creates a pointer and when used with a variable name it gets the value stored at that pointer. In the function func(), it takes 3 parameters, 1 int and 2 int pointers. I think that the first argument passed into the function is giving me an error but I am not understanding why. Shouldn't *a[0] get the value of the first element in the a array which was declared as an int?
No, the * when used on a pointer dereferences the pointer. But a[0] is already equivalent to:
*(a + 0) // And since the offset is 0, this is equivalent to *a.
In other words, dereferencing a pointer to the beginning of the array that has been offset to give you the value of the item at a given 'index'. What YOU wrote is equivalent to:
**(a + 0) // And since the offset is 0, this is equivalent to **a.
Therefore, you are trying to 'dereference' an int, which won't work. Since * is not a valid unary operator for an int, that fails and causes the error you've seen to appear.
*a[0] is the same as **a.
Given the declaration int a[10];, it should be fairly clear that you are not able to dereference a twice.
If you want the first element of the array a, then that is simply a[0].
You could also simplify your example to this, and still get the same error:
int main() {
int a[10];
int b = *a[0];
}
I encountered a problem while i type my code.
...
double* FindMax(const double* const arr, int n)
{
double max;
...
return &max;
}
int main()
{
...
maxVal = FindMax(value, numbers);
...
}
When I call the function FindMax, the program error and not allow me pass the value to function FindMax.
How can I make it possible, thanks a lot!
Two things, if maxVal is double, you cannot assign value of &max. It should be double *.
Secondly, never return address of local variable. Because once you return from function, local variable die.
I'm trying to write program that create squere for string. Squere has to be larger then string.length(). If there is word 'C++' I need 2x2 array to fill it inside.
So I have written code
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int pole(int &a,const int* l);
int main(){
string code;
cin >> code;
int wall=1;
pole(wall,code.length());
cout << wall;
system("PAUSE");
return 0;
}
int pole(int &a,const int* l){
if (a*a > l) return a;
else {
a+=1;
pole(a,l);
}
}
I bet that using pointer with recunrency save a lot of memory but I can't compile it. I'm trying to understand compilers error but is 2 hard for me ;/
Here is compiler list of errors
> in main()
11 25 Error] invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int (*)(int&, const int*)'
6 5> [Error] in passing argument 1 of 'int pole(int&, const int*)'
in pole() 17 12
>[Error] ISO C++ forbids comparison between pointer and
> integer [-fpermissive]
Here:
pole(pole, code.length());
You are passing as the second variable the result of length(), which is of type std::string::size_type, which the function pole accepts a pointer to int. Those two types are incompatible.
The second problem is that one branch of your if statement inside pole does not contain a return statement, thus giving your program Undefined Behavior.
You may want to change your function pole this way:
int pole(int &a, std::string::size_type l) {
// ^^^^^^^^^^^^^^^^^^^^^^
// Also, passing by reference is unnecessary here
if (a*a > static_cast<int>(l)) return a;
// ^^^^^^^^^^^^^^^^
// Just to communicate that you are aware of the
// signed-to-unsigned comparison here
else {
a+=1;
return pole(a,l);
// ^^^^^^
// Do not forget this, or your program will have Undefined Behavior!
}
}
Here you can see your modified program compile and run.
You are trying to use an unsigned integer (coming from std::string::length) as a pointer in:
pole(wall,code.length());
Change your pole declarations to:
int pole(int a, int l);
Saving memory on int is just nonsense there. Pointers are sometimes even more memory expensive than simple integers.
You should learn to save memory with huge objects instead.
int pole(int &a,const int* l){
if (a*a > l) return a;
else {
a+=1;
pole(a,l);
}
}
first, you cannot initialize int* l with size_t argument.
Also you do later comparison between address, not value pointed too.
Is this what you wanted?
Can someone please help me understand Reference and Dereference Operators?
Here is what I read/understand so far:
int myNum = 30;
int a = &myNum; // a equals the address where myNum is storing 30,
int *a = &myNum; // *a equals the value of myNum.
When I saw the code below I was confused:
void myFunc(int &c) // Don't understand this. shouldn't this be int *c?
{
c += 10;
cout<< c;
}
int main()
{
int myNum = 30;
myFunc(myNum);
cout<< myNum ;
}
int &c has the address to what's being passed in right? It's not the value of what's being passed in.
So when I do c+=10 it's going to add 10 to the memory address and not the value 30. Is that correct?
BUT... when I run this...of course with all the correct includes and stuff...it works. it prints 40.
Actually the ampersand in the function parameter list for myFunc is not an address operator, nor a bitwise and operator. It is a reference indicator. It means that within myFunc, the parameter c will be an alias of whatever argument is passed to it.
You have a few issues here.
your second line of code int a = &myNum; // a equals the address where myNum is storing 30 is wrong;
you can combine it with line 3 like so:
int *a = &myNum; // a equals the address where myNum is stored;
*a == myNum.
The type int & is read as "reference-to-int". Perhaps the Wikipedia article can help you understand what this means.
Both pieces of code are valid and your understanding of pointers in the first piece of code is correct. However, the ampersand (&) in the two pieces of code are actually different things. (Like how * is both the dereference and multiplication operator)
The second piece of code shows how the & can be used to pass variables to a function by reference. Normally if you had code like this:
int a;
void foo(int bar) {
bar = 3;
}
int main() {
a = 5;
foo(a);
// a still equals 5
}
The call to 'foo()' does not affect the variable you passed to it (bar or in this case, a). However if you changed this line:
void foo(int bar) {
to
void foo(int &bar) {
then it would affect the variable and at the end of the program above, the value of a would be 3.
In C++ when you pass things by reference using int &c you don't need to dereference. You only need to dereference pointers. If it was int *c then it would be necessary. Just remember in both cases you change the value of what was passed in the original caller so myNum is now 40.
Let's have a look at the assumptions first:
int myNum = 30;
// this won't compile. &myNum is the address of an int (an int *), not an int:
int a = &myNum;
// *a is a pointer to an int. It received the address of myNum (which is &myNum),
// and not its value
int *a = &myNum;
About the code:
void myFunc(int &c)
// c is passed by reference. This is a kind of "hidden pointer" that
// allows using the variable as if it was not a pointer but the pointed variable.
// But as this reference and the variable that was passed by the caller (myNum
// in your example) share the same address (this is the property of a reference),
// any modification of the value of c inside myFunc modifies it in the
// caller's scope too (so here, it modifies myNum).
{
c += 10;
cout<< c;
}
int main()
{
int myNum = 30;
myFunc(myNum); // displays 40
// What follows displays 40 as well, due to the fact
// c was passed by reference to myFunc that added 10 to it
cout<< myNum ;
}
So when I do c+=10 it's going to add 10 to the memory address and not
the value 30. Is that correct?
No, 10 was added to the value of c by myFunc.
As c is a reference (a "hidden pointer to") that received myNum, myNum was modified as well.