Returning pointer by a function

Is this a legal operation? And would it work the same with char* pointer?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    class someClass {
        int value;
        int* pointer;
      public:
        someClass();
        int* getPtr() const;
        ~someClass();
    };
    class anotherClass : public someClass {
        int value;
        int sum;
      public:
        anotherClass();
        int getValue() const;
    }
   

    someClass::someClass() {
        value = 2;
        pointer = new int[1];
        pointer = value;
    }
    someClass::~someClass() {
        delete pointer;
    }
    int* someClass::getPtr() const {
        return pointer;
    }
    anotherClass::anotherClass() {
        value = 10 + someClass::getPtr() const;
    }
    int anotherClass::getValue() {
        return value;
    }


    int main ()
    {
        std::cout << "The anotherClass Value is: " << anotherClass::getValue() << endl;
        // will it return 12?
        return 0;
    }
Last edited on
Line 21: You're setting pointer to memory address 2. Probably going to cause a memory fault if you try an reference it. You probably meant *pointer = value;

Line 21: This is also going to cause a memory leak because you just overlaid the pointer that was allocated at line 20.

Line 30: Yes, this is going to return 12 and it's "legal", but probably not what you intended.
The keyword const here is wrong. What I think you meant here is:
value = 10 + *someClass::getPtr(); // Note the * to dereference the pointer



Hello chuvak,

You should compile and check the errors. There is a lot that can be learned from them.

Like line 21 you are trying to store an int into a variable that holds an address. What you need to do is dereference the address, or pointer, to store the value. *pointer = value;.

Line 30 you are trying to add an address of a variable to an int and then store it into an int. This does not work. Again you need to dereference the pointer address to get to its value like value = 10 + *(someClass::getPtr());. In this cae you use the () because you are using the return value not a direct variable.

Line 39 is not the way to call the function. The comments in the program should help and the changes I made to main should help explain what is going on.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>

class someClass
{
	int value;
	int* pointer;
public:
	someClass();
	int* getPtr() const;
	~someClass();
};

class anotherClass : public someClass
{
	int value;
	int sum;
public:
	anotherClass();
	int getValue() const;  // <--- Added const.
};  // <--- Missing semicolon.


someClass::someClass()
{
	value = 2;
	pointer = new int[1];
	*pointer = value;
}
someClass::~someClass()
{
	delete pointer;
}
int* someClass::getPtr() const
{
	return pointer;
}
anotherClass::anotherClass()
{
	value = 10 + *(someClass::getPtr());// const;
}
int anotherClass::getValue() const  // <--- Added const.
{
	return value;
}


int main()
{
	anotherClass class2;  // <--- Define an object of the class.

	std::cout << "\n The anotherClass Value is: " << class2.getValue() << std::endl;
	// will it return 12?

	std::cout << "\n The address of the pointer is: " << class2.getPtr() << std::endl;

	std::cout << "\n The value of the pointer is: " << *(class2.getPtr()) << std::endl;
	//  Pointer still has a value of 2.
	return 0;
}


Hope that helps,

Andy
Thank you both, Im starting to understand.

This was a general case, but my specific issue is that Class1 has a data member array of characters to store name. I cannot return an array, (which is what I need to do), so instead I said Class1 has also a pointer as a data member. So, upon instantiation of a Class1 object in the Class1 constructor, I initialize the pointer to the array.

Class1 therefore has the Class1::getName() const; function, which returns the pointer to the array. So if a Class2 function ever needs the name array, it can simply call the Class1::getName() member function from Class1, and it will have the name.

However, it doesnt work, unfortunately:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

	class Class1 {
		char name[41];
                int health;
                int strength;
		char* Ptr;
	public:
		Class1(const char* str, const int hp, const int at);
		virtual void setEmpty(); //virtual because setEmpty() is redefined in Class2
		char* getName() const;
	};

	Class1::Class1(const char* str, const int hp, const int at) {
		if (str && hp && at) {
			strcpy(name, str);
			health = hp;
			strength = at;
			*Ptr = name; //initially I had 'Ptr = name' before reading your comments (which didnt work, either)
                        //now though, it just underlines '=' in red and doesnt compile: 'a value of char* cannot be assigned to char'
		}
		else {
			setEmpty();
		}
	}

	char* Class1::getName() const {
		return Ptr; //should it be  return *Ptr; ?
	}


If I try to run something like this, I get a read access violation:

1
2
3
void Class2::getName() const {
    std::cout << "Name is: " << this->Class1::getName() << std::endl;
}


Why, if Class2 is derived from Class1?
Last edited on
If I try to run something like this, I get a read access violation:

You still haven't answered my question as to whether the string passed to strcpy() is properly terminated with a null character. As I've explained before, if it is not, strcpy will happily keep copying past the 41 characters allocated for name. This can cause either a read access violation, a write access violation or numerous other problems.

Line 18: Ptr is not needed. getName can simply return name, which is a pointer to the base of the char array.

Line 27: No. getName() is correct as is. Returning *ptr would give you a type mismatch on the return as you would be trying to return a single character whereas the return type is a pointer.

You still haven't answered my question

On line 15, strcpy(name, str);, str is passed like this,

 
Class1 aClass("Superman", 30, 3)


So when I say strcpy(name, str);, it should properly copy the string, no? Or as you saying I should make name[strlen(str) + 1] = '\0';

--

Line 18: Ptr is not needed

It is because I later have a function like this:
const Class2& operator* (const Class2& first, const Class2& second)
and I make copies of first and second in this function. Because of the const qualifiers and nature of the function itself, I cannot, within this function, run another function that isn't const.

Which means I cannot run Class1::getName(){} within this function because getName involves dynamically allocating memory and/or changing where the member pointer points to.

Because of the const, I cant even run getName() if it declares and destroys a pointer within itself, ie

1
2
3
4
5
char* pointer = first.Class1::getName();
Class1::getName() {
     char* p_pointer = name;
     return p_pointer;
}


Class1::getName() {} must be const / a query
Last edited on
it should properly copy the string,

Yes, passing a quoted literal will be properly terminated with a null.

Or as you saying I should make name[strlen(str) + 1] = '\0';

No. Note that strlen() also requires that the passed string is properly terminated, so if the passed string wasn't properly terminated, strlen() will happily keep scanning memory until it finds a null, or traps with a read access violation.

I cannot, within this function, run another function that isn't const.

Class1::getName should be const. A function being const does not mean that you can not run another function that isn't const, it means that you can't do anything that changes the instance of the class.

In the snippet you posted, you have a problem at line 1. pointer should be const char *. getName() is declared as const, so your assigning the return value to a pointer that is not const is breaking the agreement that you won't change the instance.

Again, I strongly recommend the use of std::string. It is actually mush simpler and safer to use than C strings.

Here's your above snippet using std::string:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <string>
using namespace std;

class Class1 
{   string  name;
    int health;
    int strength;
public:
	Class1 (const string & str, const int hp, const int at);
	virtual void setEmpty(); //virtual because setEmpty() is redefined in Class2
	string getName() const;
};

Class1::Class1 (const string & str, const int hp, const int at) 
{   if (! str.empty() && hp && at)
    {   name = str;
        health = hp;
	    strength = at;
    }
    else
        setEmpty ();
}        

string Class1::getName() const 
{   return name; 
}

Last edited on
Thank you for the help. I have made necessary changes, but still I am stuck

const Class2& operator* (const Class2& first, const Class2& second)

The first line I wrote in this function (note, it is from Class2), is

std::cout << "Name is: " << first.Hero::getName() << std::endl;

and I run into a read-access violation.

Im trying to understand why this is happening. Does my derived Class2 have no access to the name array in Class1? Because of this issue, I cannot do something like,

1
2
3
4
5
6
7
8
Class2::someFunction () {
     const char* f_pointer = first.Class1::getName();
     std::cout << "Name is: " << f_pointer << std::endl; //access violation
}

char* Class1::getName() const {
	return Ptr;
}


I also have a destructor, Class1::~Class1() {} , perhaps it'd deleting the Ptr somehow? (i havent created a destructor with that functionality, so that really shouldnt be an issue)

We havent learned std::string yet, unfortunately. I keep hearing that it is a much better solution, but if we havent learned it, I cant use it in my code when I submit my work.
Last edited on
I run into a read-access violation.

At this point, my only suggestion is that you step through the code with a debugger.

Does my derived Class2 have no access to the name array in Class1?

Since name is private in Class1, Class2 has no direct access to it. It can however access it using a public getter in Class1.

Line 6: The return type of Class1::getName should be const char *.

perhaps it'd deleting the Ptr somehow?

No. If your destructor has no statements, it's not deleting Ptr.


Does your Class1 have a default constructor? If so, what initialization does it do?
Last edited on
I'm not sure about it but I would recommend to try avoid these as they can cause some errors in the code that are going to be hard to detect unless you use dome program as checkmarx or other equivalent.
i'd honestly recommend to work slowly and detect those problem on the go, in order to save your time.
Good luck.
Topic archived. No new replies allowed.