Having trouble accessing memory location of private class member

I get the following runtime error when trying to access the private member char *name. Can somebody give me suggestions on how to get rid of the run time error on the line in >> rhs.name;

DEBUG CALL STACK

> msvcp90d.dll!std::operator>><char,std::char_traits<char> >(std::basic_istream<char,std::char_traits<char> > & _Istr={...}, char * _Str=0x001d79d1) Line 983 + 0x15 bytes C++
6c_Library.exe!operator>>(std::basic_istream<char,std::char_traits<char> > & in={...}, Member & rhs={...}) Line 56 + 0x16 bytes C++
6c_Library.exe!Member::setMember() Line 42 + 0x10 bytes C++
6c_Library.exe!main() Line 27 C++
6c_Library.exe!__tmainCRTStartup() Line 582 + 0x19 bytes C
6c_Library.exe!mainCRTStartup() Line 399 C
kernel32.dll!75f233ca()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!774a9ed2()
ntdll.dll!774a9ea5()

CLASS DECLARATION

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
#ifndef MEMBER_H
#define MEMBER_H

#include <iostream>
#include <string>
#include <iomanip>
#include <stdlib.h>
#pragma warning(disable:4996)

using namespace std;

class Member
	{
	friend std::istream& operator>> (std::istream&, Member&);
	friend std::ostream& operator<< (std::ostream&, const Member&);

	protected:
		int id;
		char *name;
		
	public:
		~Member();//default destructor
		Member();//default constructor
		Member(char*, int);//copy constructor
		void copy(Member&);//copy function
		void operator= (Member&);
		void setMember();//set member function
		Member& getMember();//get member function
	};

#endif 

CLASS IMPLEMENTATION

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
60
61
62
63
64
65
66
67
68
#include "Member.h"

using namespace std;

//Implementation of default destructor
Member::~Member()
	{
	}

//Implementation of default constructor
Member::Member()
	{
	name = "";
	id = 0;
	}

//Implementation of copy constructor
Member::Member(char *N1, int ID1)
	{
	name = new char [strlen(N1)+1];
	strcpy (name, N1);
	id = ID1;
	}

//Implementation of copy function
void Member::copy(Member& M1)
	{
	name = M1.name;
	id = M1.id;
	}

//Implementation of =operator
void Member::operator =(Member& M1)
	{
	name = M1.name;
	id = M1.id;
	}

//Implementation of set function to input data
void Member::setMember()
	{
	cin >> *this;
	}

//Implementation of get fuction to output data
Member& Member::getMember()
	{
	cout << *this;
	return *this;
	}

//Input function
istream& operator>>(istream& in, Member& rhs)
	{
	cout << "Please enter member name (use underscore in place of space).\t";
	in >> rhs.name;
	cout << "Please enter the member's id.\t";
	in >> rhs.id;
	return in;
	}

//Function to use cout
ostream& operator<<(ostream& out, const Member& rhs)
	{
	out << "The member's name is " << rhs.name 
		<< " and the member's id is " << rhs.id << ".";
	return out;
	}
Last edited on
Please edit your post and put the source inside code tags. It will make your post a lot more legible and folks here will be more likely to look at it.
[code] "Please use code tags" [/code]
Use std::string instead of char *
1
2
3
4
5
6
7
8
9
10
11
12
13
//Implementation of default constructor
Member::Member()
{
  name = ""; //<---
  id = 0;
}

istream& operator>>(istream& in, Member& rhs)
{
  cout << "Please enter member name (use underscore in place of space).\t";
  in >> rhs.name; //<--- (crash)
//...
}

You have memory leaks, and in your operator= (and in the copy constructor) you are not copying the content but pointing to the same position
Thank you for taking the time to respond. This was my first post and didn't know about the source code tags, thanks for the correction. I am in my second C++ class and unfortunately I can't change from char * because that is what is specified in my assignment. The other classes I have built using this method have worked fine. Could you be a little more specific on what I need to change because I'm not following what you mean by memory leaks. I understand what they are to an extent but still apparently don't know how to prevent them. Once again thank you for you help.
Is dynamic allocation a requisite too?
name = ""; //warning: deprecated conversion from string constant to 'char*'
When you try to write the name there, you don't have the permissions (you didn't reserve space)

About the memory leaks:
Everything that you allocate with new, you must deallocate with delete.
Everything that you allocate with new [], you must deallocate with delete [].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Implementation of copy constructor a constructor
Member::Member(char *N1, int ID1)
	{
	name = new char [strlen(N1)+1]; //created with new[]
	strcpy (name, N1);
	id = ID1;
	}
Member::~Member()
	{ //there is no delete[] here
	}
void Member::operator =(Member& M1) //same for Member::copy
	{
	name = M1.name; //dangerous, how will you avoid a double freeing?
	                             //Also, whatever that this->name pointed before, you lost it
	id = M1.id;
	}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Implementation of copy constructor a constructor
Member::Member(char *N1, int ID1)
	{
	name = new char [strlen(N1)+1]; //created with new[]
	strcpy (name, N1);
//I should add delete N1[] here then?
	id = ID1;
	}
Member::~Member()
	{ //there is no delete[] here
        }
void Member::operator =(Member& M1) //same for Member::copy
	{
	name = M1.name; //dangerous, how will you avoid a double freeing? 
                                            //I don't understand what you mean by the term double freeing. 
	                             //Also, whatever that this->name pointed before, you lost it
                                            //So should I create a new space and delete it? 
	id = M1.id;
	}
yes dynamic allocation is a requisite as well.
name = ""; //warning: deprecated conversion from string constant to 'char*'
So how do I correct this? I haven't run into this problem yet. Thanks ne555 for your help.
Last edited on
You delete the array when you end using it (by instance in the destructor, or in a reallocation)
Double free
1
2
3
4
5
6
7
int *ptr = new int[42];
delete [] ptr;
delete [] ptr; //deleting the same position twice, crash[code]

[code]void Member::operator =(Member& M1) //same for Member::copy
	{
	name = M1.name;
Instead of that you need to copy the content. You could use strcpy, provided that you have enough space in the destination.
If you don't have enough space you need to allocate it.

About the default constructor: keep an invariant. By instance set the pointer to NULL, or to new char[42];

Keep in mind that you will need a variable that tells you how much space do you have reserved by the pointer. In the end you will be emulating std::string.
Thank you for your help.
Topic archived. No new replies allowed.