Passing character pointers into a function and dynamically allocating memory
-
18-06-2021 - |
Question
Student.h
class Student
{
private:
char m_sHouse[64];
public:
Student(void);
~Student(void);
void getHouse(char *hName);
void setHouse(char *hName);
}
Student.cpp
void Student::setHouse(char *hName)
{
strcpy(m_sHouse, hName);
}
void Student::getHouse(char *hName)
{
if (m_sHouse != NULL)
{
hName = new char[strlen(m_sHouse)+1];
strcpy(hName, m_sHouse);
}
}
In main:
student.getHouse(house);
if (strcmp(house, "house") == 0)
cout <<"\tCorrectly returned the student house: " << house<< endl;
setHouse(char *hName)
sets student->m_sHouse
equal to "house".
My question:
When inside getHouse(char *hName)
, it acts as it should, setting hName
to "house". but when control is passed out of the function, my dynamically allocated memory is deallocated, so when I strcmp in main, my program crashes (I end up comparing a NULL pointer).
Solution
Nick, the proper solution is that you know that hName
is already allocated by the user of the class (Dr. Coleman). You simply need to strcpy
into the character array.
Simply put:
void Student::getHouse(char *hName)
{
strcpy(hName, m_sHouse);
}
OTHER TIPS
You are allocating new memory and assigning it to a local variable. Change your function to
void Student::getHouse(char **hName)
{
if (m_sHouse != NULL)
{
*hName = new char[strlen(m_sHouse)+1];
strcpy(*hName, m_sHouse);
}
}
This will change the address pointed to by the argument passed in to your function, not the copy of it
The pointer hname
is a copy of house
(the pointer you have passed to getHouse
). Inside that function you change hname
, however, you are not changing the original house
! To do that, you should either return the allocated memory:
char *Student::getHouse()
{
char *hame = NULL;
if (m_sHouse != NULL)
{
hName = new char[strlen(m_sHouse)+1];
strcpy(hName, m_sHouse);
}
return hname;
}
and then
house = student.getHouse();
or give a pointer to this variable, so that it can be changed:
void Student::getHouse(char **hName)
{
if (m_sHouse != NULL && hname != NULL)
{
*hName = new char[strlen(m_sHouse)+1];
strcpy(*hName, m_sHouse);
}
}
and then
student.getHouse(&house);
Similarly, you can give a reference to the house variable:
void Student::getHouse(char *&hName)
{
if (m_sHouse != NULL)
{
hName = new char[strlen(m_sHouse)+1];
strcpy(hName, m_sHouse);
}
}
and then
student.getHouse(house);
The better solution however, would be to use std::string
instead.
void Student::getHouse(char *hName)
{
if (m_sHouse != NULL)
{
hName = new char[strlen(m_sHouse)+1];
strcpy(hName, m_sHouse);
}
}
This only modifies a copy of hName
pointer and does not modify the original pointer. To modify it you need to pass a pointer to your pointer:
void Student::getHouse(char **hName)
{
if (m_sHouse != NULL)
{
*hName = new char[strlen(m_sHouse)+1];
strcpy(*hName, m_sHouse);
}
}
and call your function like this:
student.getHouse(&house);