CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Dec 2020
    Posts
    2

    Why will this not work out?

    Hi all,

    I've now come back to my roots programming C++. It's been a while and I have clearly lost toutch. It not like riding a bike, once you've learned it you wount forgett it...

    My question:
    Below I've got some code written in the Repl.it online environment. As you can see I have a class I call ValueBox in it I have a private section and a public. There are a number of set functions and some get functions as well. I use pointers just to see if I can get back to understanding them again, but I clearly have some issues. When I set and get data the way you see it below it works out, but I had originally the code you see at the end, the code that has been commented out. If I try doing it in this (commented) way I get unpredictable results, why?

    #include <iostream>
    using namespace std;

    class ValueBox {
    private:
    int *intMyValue;
    string *strMyValue;
    double *dblMyValue;

    public:
    /************* Set the values of private members *************/
    void setValue(int intLocalVar) { intMyValue = &intLocalVar; }
    void setValue(string strLocalVar) { strMyValue = &strLocalVar; }
    void setValue(double dblLocalVar) { dblMyValue = &dblLocalVar; }

    /************* Get the values of private members *************/
    int getIntValue() { return *intMyValue; }
    string getStrValue() { return *strMyValue; }
    double getDblValue() { return *dblMyValue; }
    };

    int main() {
    ValueBox *myValueBox = new ValueBox();

    /******************** This works *********************/
    //Sets & Gets an integer
    myValueBox->setValue(25);
    cout << myValueBox->getIntValue() << endl;
    //Sets & Gets a string
    myValueBox->setValue("Hej!");
    cout << myValueBox->getStrValue() << endl;
    //Sets & Gets an double
    myValueBox->setValue(3.5);
    cout << myValueBox->getDblValue() << endl;

    delete myValueBox;
    }

    /******************** This wount work, why? *********************
    //Set
    myValueBox->setValue(25);
    myValueBox->setValue("Hej!");
    myValueBox->setValue(3.5);
    //Get
    cout << myValueBox->getStrValue() << endl;
    cout << myValueBox->getIntValue() << endl;
    cout << myValueBox->getDblValue() << endl;
    */

    It might be a pretty simple problem, but I don't want leave it behind without understanding why I get a strange outcome.

    Happy new year to you all.
    Kennet

  2. #2
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Why will this not work out?

    There's a basic misunderstanding here. Even the code that seems to work isn't correct.

    Code:
    void setValue(int intLocalVar) { intMyValue = &intLocalVar; }

    This sets the value of intMyValue ( an int pointer) to the address of intLocalVar. However intLocalVar only 'exists' for the duration of the setValue() function. Once the setValue() function returns the address of intLocalVar is invalid. When intMyValue is then dereferenced, an attempt is made to dereference an 'invalid' address. This is undefined behaviour. It may work if the moons are aligned with the planets on the even days - but it is 'fragile code' at best.

    If intMyValue is required to be a pointer (??), then allocate memory for it and copy the value to the new memory from that passed in. The same for the other pointer class variables. Then you need at minimum copy/move constructors. copy/move operator= and destructor.
    Last edited by 2kaud; December 30th, 2020 at 08:17 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Why will this not work out?

    Consider:

    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class ValueBox {
    private:
    	int intMyValue {};
    	string strMyValue {};
    	double dblMyValue {};
    
    public:
    	/************* Set the values of private members *************/
    	void setValue(int intLocalVar) noexcept { intMyValue = intLocalVar; }
    	void setValue(string strLocalVar) { strMyValue = strLocalVar; }
    	void setValue(double dblLocalVar) noexcept { dblMyValue = dblLocalVar; }
    
    	/************* Get the values of private members *************/
    	int getIntValue() const noexcept { return intMyValue; }
    	string getStrValue() const { return strMyValue; }
    	double getDblValue() const noexcept { return dblMyValue; }
    };
    
    int main() {
    	auto myValueBox {new ValueBox {}};
    
    	/******************** This NOW works *********************/
    	//Sets & Gets an integer
    	myValueBox->setValue(25);
    	cout << myValueBox->getIntValue() << '\n';
    
    	//Sets & Gets a string
    	myValueBox->setValue("Hej!");
    	cout << myValueBox->getStrValue() << '\n';
    
    	//Sets & Gets an double
    	myValueBox->setValue(3.5);
    	cout << myValueBox->getDblValue() << '\n';
    
    	//******************** This ALSO NOW work *********************
    	auto myValueBox1 {new ValueBox {}};
    
    	//Set
    	myValueBox1->setValue(25);
    	myValueBox1->setValue("Hej!");
    	myValueBox1->setValue(3.5);
    
    	//Get
    	cout << myValueBox1->getStrValue() << '\n';
    	cout << myValueBox1->getIntValue() << '\n';
    	cout << myValueBox1->getDblValue() << '\n';
    
    	delete myValueBox;
            delete myValueBox1;
    }
    which displays:

    Code:
    25
    Hej!
    3.5
    Hej!
    25
    3.5
    Last edited by 2kaud; December 30th, 2020 at 08:28 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Why will this not work out?

    If you want the class variables to be pointers, then something like:

    Code:
    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    class ValueBox {
    private:
    	int* intMyValue {};
    	string* strMyValue {};
    	double* dblMyValue {};
    
    public:
    	ValueBox() : intMyValue(new int {}), strMyValue(new string), dblMyValue(new double {}) {}
    
    	~ValueBox() {
    		delete intMyValue;
    		delete strMyValue;
    		delete dblMyValue;
    	}
    
    	ValueBox(const ValueBox& vb) : ValueBox() {
    		*intMyValue = *vb.intMyValue;
    		*strMyValue = *vb.strMyValue;
    		*dblMyValue = *vb.dblMyValue;
    	}
    
    	void swap(ValueBox& vb) noexcept
    	{
    		std::swap(intMyValue, vb.intMyValue);
    		std::swap(strMyValue, vb.strMyValue);
    		std::swap(dblMyValue, vb.dblMyValue);
    	}
    
    	ValueBox& operator=(const ValueBox& vb)
    	{
    		ValueBox vb1(vb);
    
    		swap(vb1);
    		return *this;
    	}
    
    	ValueBox(ValueBox&& vb) noexcept
    	{
    		swap(vb);
    	}
    
    	ValueBox& operator=(ValueBox&& vb) noexcept
    	{
    		swap(vb);
    		return *this;
    	}
    
    	/************* Set the values of private members *************/
    	void setValue(int intLocalVar) noexcept { *intMyValue = intLocalVar; }
    	void setValue(string strLocalVar) { *strMyValue = strLocalVar; }
    	void setValue(double dblLocalVar) noexcept { *dblMyValue = dblLocalVar; }
    
    	/************* Get the values of private members *************/
    	int getIntValue() const noexcept { return *intMyValue; }
    	string getStrValue() const { return *strMyValue; }
    	double getDblValue() const noexcept { return *dblMyValue; }
    };
    
    ostream& operator<<(ostream& os, const ValueBox& vb)
    {
    	return os << vb.getIntValue() << '\n' << vb.getDblValue() << '\n' << vb.getStrValue() << '\n';
    }
    
    int main() {
    	auto myValueBox {new ValueBox {}};
    
    	myValueBox->setValue(25);
    	myValueBox->setValue("Hej!");
    	myValueBox->setValue(2.5);
    
    	cout << *myValueBox << '\n';
    
    	auto myValueBox1 {new ValueBox {}};
    
    	myValueBox1->setValue(45);
    	myValueBox1->setValue("Hej!");
    	myValueBox1->setValue(4.5);
    
    	cout << *myValueBox1 << '\n';
    
    	auto myValueBox2 {new ValueBox(*myValueBox)};
    
    	cout << *myValueBox2 << '\n';
    
    	*myValueBox2 = *myValueBox1;
    	cout << *myValueBox2 << '\n';
    
    	delete myValueBox;
    	delete myValueBox1;
    	delete myValueBox2;
    }
    Code:
    25
    2.5
    Hej!
    
    45
    4.5
    Hej!
    
    25
    2.5
    Hej!
    
    45
    4.5
    Hej!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Dec 2020
    Posts
    2

    Re: Why will this not work out?

    Thanks!

    I will look into the answers as soon as I get a chance.
    I might get back to you if there are things I don't understand

    For now, A Happy New Year! and thanks

    Kennet

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured