c++ how to access variable from member function? - c++

I have a problem. I want to operate with single element of an array, which is generated in member function, but it doesn´t work. Here is my code:
using namespace std;
class Example
{
public:
int *pole;
void generate_pole();
};
void Example::generate_pole()
{
int *pole = new int [10];
for (int i = 0; i < 10; i++)
{
pole[i] = i;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Example reference;
reference.generate_pole();
cout << reference.pole[1] << endl; //there is the problem
system("pause");
return 0;
}
How can I get an access to the element? And where is the real problem? Thank you!

int *pole = new int [10]; is creating an identically named variable pole in local scope. This is shadowing the member variable.
A fix, drop the int* from the errant line: pole = new int [10];
That said, I'd be inclined to use a constructor to set the member variable in this case: certainly you should initialise pole to nullptr by default. This is so you can delete[] pole in a destructor when an instance of your class goes out of scope. Else your code will leak memory like a colander leaks water.
An other way would be to use std::vector<int> pole; and let the C++ standard library take care of all the memory for you.

The problem is, that you shadow pole's name in the scope of the function by redeclaring it. leave the int * in front of pole behind, in generate_pole, and it should work.
An example for shadowing:
int i = 0; // i is 0
std::cout << "before scope: " << i << std::endl; // prints 0
{
int i = 1;
std::cout << "inside scope: " << i << std::endl; // prints 1
}
std::cout << "behind scope: " << i << std::endl; // prints 0

Related

Memory fault when print *pointer

Why do I have a memory fault in the below code? How do I fix it?
I want to read the progress of the outside function.
But I only get the output get_report_progress:100
#include <iostream>
int* int_get_progress = 0;
void get_progress(int* int_get_progress)
{
int n = 100;
int *report_progress = &n;
int_get_progress = report_progress;
std::cout << "get_report_progress:" << *int_get_progress <<std::endl;
}
int main()
{
get_progress(int_get_progress);
std::cout << "main get process:" << *int_get_progress << std::endl;
return 0;
}
Your global int_get_progress variable is a pointer that is initialized to null. You are passing it by value to the function, so a copy of it is made. As such, any new value the function assigns to that pointer is to the copy, not to the original. Thus, the global int_get_progress variable is left unchanged, and main() ends up deferencing a null pointer, which is undefined behavior and in this case is causing a memory fault.
Even if you fix the code to let the function update the caller's pointer, your code would still fail to work properly, because you are setting the pointer to point at a local variable that goes out of scope when the function exits, thus you would leave the pointer dangling, pointing at invalid memory, which is also undefined behavior when that pointer is then dereferenced.
Your global variable (which doesn't need to be global) should not be a pointer at all, but it can be passed around by pointer, eg:
#include <iostream>
void get_progress(int* p_progress)
{
int n = 100;
*p_progress = n;
std::cout << "get_report_progress:" << *p_progress << std::endl;
}
int main()
{
int progress = 0;
get_progress(&progress);
std::cout << "main get process:" << progress << std::endl;
return 0;
}
Alternatively, pass it by reference instead, eg:
#include <iostream>
void get_progress(int& ref_progress)
{
int n = 100;
ref_progress = n;
std::cout << "get_report_progress:" << ref_progress << std::endl;
}
int main()
{
int progress = 0;
get_progress(progress);
std::cout << "main get process:" << progress << std::endl;
return 0;
}
Alternatively, don't pass it around by parameter at all, but return it instead, eg:
#include <iostream>
int get_progress()
{
int n = 100;
std::cout << "get_report_progress:" << n << std::endl;
return n;
}
int main()
{
int progress = get_progress();
std::cout << "main get process:" << progress << std::endl;
return 0;
}

references in c++ with static

Below is a output question.I am not able to understand why its answer is 30.
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
static int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
OUTPUT:30
Can anybody tell why output is coming to be 30 and also can explain the role of static keyword
In computer programming, a static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program
void foo()
{
int a = 10;
static int b = 10;
a++;
b++;
std::cout << "a : " << a << " , b : " << b << std::endl;
}
A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable.
int a = 4;
int b = a;
int &c = a;
c++;
std::cout << "b = " << b << std::endl; //4
std::cout << "a = " << a << std::endl; //5
std::cout << "c = " << c << std::endl; //5
/* Becaues c is a refence to a, it means that
a and c are just different names to the same memory location
so updating either one updates the actual value in memory
*/
a++;
std::cout << "c = " << c << std::endl; //6
std::cout << "a = " << a << std::endl; //6
//consider the function below:
int &bar()
{
static int a = 5;
std::cout << "a is " << a << std::endl;
return a;
}
Testing the two:
int main()
{
for (int i = 0; i < 3; i++)
foo();
//for every call of foo():
//memory allocation for a is created and deleted when a goes out of scope
//memoery allocation for b extends through out the life of the program
//bar() returns a reference to "a" i.e
int reference_to_a = bar(); //prints 5
reference_to_a = 30;
bar(); //prints 30
bar() = 50; //prints 30 and later assigns 50 to the reference returned.
bar(); //prints 50
}
static make the variable persist across function calls.
which means static int x = 10; will be executed once when func is called for the first time.
int static_test()
{
static int x = 10;
x++;
return x;
}
static_test(); // first call will return 11
static_test(); // second call will return 12 because the value of x ( was saved and was then incremented)
static_test(); // third call will return 13
Now, you need to understand what reference are. To understand what reference are you need to understand pointers. I am guessing you will easily find some website explaining those two.
case 1:
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
Here, in the call fun(), we are declaring a local variable int x, which goes out of scope once it returns from fun().
so, in the line cout << fun() a new variable is declared and address of the new variable is returned.
case 2:
static int x = 10;
here, since variable 'x' is static, it can be initialized only once. i.e., the first time x is initialized to 5 and then over written to 30.
now when you are making the function call subsequent times, static int x = 5 is ignored. Hence, it returns the value 30

Memory Corruption in C++ program

I'm trying to improve my C++ by writing a game of Conway's life.
The GameBoard object is getting corrupted. I call its print() method directly from the Game object constructor and it works. I then call it indirectly via from Game's print_board method and get an error on an integrity check.
Also, in main, there is a declaration of a variable I never use, but if I remove it, the error goes away. Somehow, I'm doing something to corrupt memory. It's probably pretty obvious.
Any assistance is greatly appreciated!
#include <iostream>
using namespace std;
class Board {
int size;
int grid[100][100];
public:
Board(int board_size) {size = board_size;}
void print() {
cout << "Board::print()" << endl;
if (size < 1) {cout << "print: size must be > 0: size=" << size << "\n"; exit(1);}
}
};
class GameRuleSet { }; // Methods removed
class Game {
private:
Board * game_board;
GameRuleSet * rule_set;
public:
Game (GameRuleSet * p_rule_set, int p_board_size) {
Board * game_board = new Board(p_board_size);
cout << "Second Call - indirect..." << endl;
game_board->print();
cout << "Second Call - direct..." << endl;
this->print_board(); // Error manifests from here
}
void print_board() {game_board->print();}
};
int main () {
int num_turns = 10; // This line manifests error.
int board_size = 10;
GameRuleSet rule_set = GameRuleSet();
Game game = Game(&rule_set, board_size);
}
You are re-declaring "Board* game_board" in your constructor which shadows the member variable of the same name. It then uses that allocated local game_board in the constructor to print.
In the print_board() function it uses the unallocated member and therefore throws the error.
Change the allocation from
Board * game_board = new Board(p_board_size);
to
game_board = new Board(p_board_size);
in the constructor to fix this.

Visual Studio C++ access violation when modifying a pointer passed into a function

I want to implement a simple function that gets a string as a char pointer and modifies the string in a function. The requested function must be void then I have to modify the primary string passed into my function. I got an access violation error and googled it but nothing helped.
My sample code is here:
#include "iostream"
using namespace std;
void FindCommonStr(char*& Common,int &A)
{
int i=0;
while(1)
{
if(Common[i]=='\0')
break;
i++;
}
cout<<"Number of Elements = "<<i<<endl;
for (int j=0 ; j<i-1;j++)
Common[j]='y';
A=2;
}
void main()
{
int A=0;
char* Common = new char;
Common = "Hello World!";
cout<<"Common0 = "<< Common<<endl;
cout<<"A0 = "<< A<<endl;
FindCommonStr(Common,A);
cout<<"Common1 = "<< Common<<endl;
cout<<"A1 = "<< A<<endl;
}
Actually the problem occured in this part of FindCommonStr funtion:
for (int j=0 ; j<i-1;j++)
Common[j]='y';
If I comment this part everything works but I cannot change the string values. I also tested the pointer to pointer solution by defining the function as:
FindCommonStr(char **Common,...
It doesn't help though and I got the violation error again.
Is it even possible to do such a thing?
When you do this:
Common = "Hello World!";
you are making the pointer Common point at a literal C-style string (and incidentally leaking the original char that you allocated via new previously). It is not valid to try to modify such a literal, so when you pass this to FindCommonStr and try to modify it you get an access violation.
You should avoid using C-style strings and use proper C++ std::string instead - this will save a lot of problems and is much more robust, as well as being more appropriate for C++ programming.
Fixed version of your code:
#include <iostream>
#include <string>
using namespace std;
static void FindCommonStr(string &Common, int &A)
{
int i = 0;
while (1)
{
if (Common[i] == '\0')
break;
i++;
}
cout << "Number of Elements = " << i << endl;
for (int j = 0; j < i - 1; j++)
Common[j] = 'y';
A = 2;
}
int main()
{
int A = 0;
string Common = "Hello World!";
cout << "Common0 = " << Common << endl;
cout << "A0 = " << A << endl;
FindCommonStr(Common, A);
cout << "Common1 = " << Common<<endl;
cout << "A1 = " << A << endl;
return 0;
}
Alternatively if this is a homework assignment where you are required to use C strings for some unfathomable reason then a fixed version using only char * strings might look like this:
#include <iostream>
using namespace std;
static void FindCommonStr(char *Common, int &A)
{
int i = 0;
while (1)
{
if (Common[i] == '\0')
break;
i++;
}
cout << "Number of Elements = " << i << endl;
for (int j = 0; j < i - 1; j++)
Common[j] = 'y';
A = 2;
}
int main()
{
int A = 0;
char Common[] = "Hello World!";
cout << "Common0 = " << Common << endl;
cout << "A0 = " << A << endl;
FindCommonStr(Common, A);
cout << "Common1 = " << Common<<endl;
cout << "A1 = " << A << endl;
return 0;
}
This part is conceptually wrong:
char* Common = new char;
// 'Common' is set to point to a piece of allocated memory
// (typically located in the heap)
Common = "Hello World!";
// 'Common' is set to point to a constant string
// (typically located in the code-section or in the data-section)
You are assigning variable Common twice, so obviously, the first assignment has no meaning.
It's like writing:
int i = 5;
i = 6;
On top of that, you "lose" the address of the allocated memory block, so you will not be able to release it at a later point in the execution of your program.
You seem to mixup char[] and string
When you write
char* Common = new char;
you allocate space on the heap for one character which Common is pointing to.
Then you write
Common = "Hello World!";
which sets the pointer Common to point to the string "Hello World" in read-only memory. The heap you allocated previously is now leaked.
There are basically two approaches:
Either you work with arrays of characters, in that case you write something like
char* Common = new char[strlen("Hello World!")+1];
strcpy(Common, "Hello World!");
Now common still points to the heap and the string has been copied there. The extra +1 byte is to hold the ending \0 string terminator.
You need to free the memory Common points to once you are done.
delete Common;
The other approach is to use the string template
std::string Common;
this allows you to assign a string, it capsules all the work with the heap array above.
Common = "Hello World!";
and there is no need to delete anything afterwards since std::string will do that for you.

accessing the member of a class of pointer array of another class

I'm trying to figure out how I can or why I can't access the member of this class. First I'll show you what works so you know what I'm thinking, then I'll show you what I can't seem to do.
What I can do is this: I have a class with a member. I make an pointer array of that class and make NEW pieces of it (through loop) and that's fine and all. I can also make another class with a similar array and even make NEW instances of that as well and initialize them, but when I try to access them, I have problems.
This code almost works fine:
#include <iostream>
using namespace std;
class testClass{
public:
int number;
};
class testPoint{
public:
testClass testInstance;
testClass *testclassArray[5];
void makeArray();
void setToI();
};
void testPoint::makeArray(){
for (int i = 0; i < 5; i++){
testclassArray[i] = new testClass;
}
}
void testPoint::setToI(){
for (int i = 0; i < 5; i++){
(*testclassArray[i]).number = i;
}
}
int main(void){
testPoint firstTestPoint;
firstTestPoint.makeArray();
firstTestPoint.setToI();
// EXCEPT FOR THIS LINE this is where I have problems
cout << firstTestPoint.(*testclassArray[0]).number << endl;
return 0;
}
I know this should work becuase this works
int main(void){
testPoint firstInstance;
firstInstance.testInstance.number = 3;
cout << firstInstance.testInstance.number << endl;
// and this works
return 0;
}
and this works
int main(void){
testClass *testPointer[5];
for (int i = 0; i < 5; i++){
testPointer[i] = new testClass;
(*testPointer[i]).number = i;
}
cout << (*testPointer[0]).number << endl;
return 0;
}
so why can't I access the members on the cout function the same way?
The following is invalid syntax:
cout << firstTestPoint.(*testclassArray[0]).number << endl;
The most common way to write what you are trying to accomplish is:
cout << firstTestPoint.testclassArray[0]->number << endl;
But, if you prefer, you can also write:
cout << (*firstTestPoint.testclassArray[0]).number << endl;
(The second way is far less common.)
The . operator is used to access members of direct objects, e.g. a.member where a might be declared as struct A a;. The -> operator is used to access members of indirect objects (aka pointers to objects), e.g. b->member where b might be declared as struct B* b = new B();.
You are dereferencing the variable in an incorrect way.
Try doing
cout << firstTestPoint.testclassArray[0]->number << endl;
instead.
In the same way the second attempt, where it works for you, could also have been written:
out << testPointer[0]->number << endl;
Try using this code:
cout << firstTestPoint.testclassArray[0]->number << endl;