向函数传递字符指针并动态分配内存

3

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);
     }
 }

在主函数中:

 student.getHouse(house);
 if (strcmp(house, "house") == 0)
     cout <<"\tCorrectly returned the student house: " << house<< endl;

setHouse(char *hName)函数将student->m_sHouse设为“house”。

我的问题:

当在getHouse(char *hName)函数内部时,它表现得像它应该的那样,将hName设为“house”。但是当控制权传递出函数时,我的动态分配的内存被释放了,所以当我在主函数中进行strcmp比较时,我的程序崩溃了(我最终比较了一个NULL指针)。


1
  1. 它还没有被释放。
  2. 不要这样做。
- Cat Plus Plus
1
给出的答案可以解决这个问题,但我可以问一下为什么需要这样做吗?在C++中使用strcpy通常是不被赞同的,因为你会混合不同的风格。你尝试过使用std:string吗? - Alexander Kondratskiy
1
虽然了解代码崩溃的原因很重要,但最好切换到C++字符串以完全避免这个问题。 - jlunavtgrad
1
我需要这样做是因为我的老师比较老派。他知道使用字符串是正确的方法,但他认为我们可能会遇到旧代码或者固执己见的老程序员,所以他希望我们能够熟练使用Kernighan和Ritchie字符数组。 - Nick
2
我看到有人在做Coleman博士的作业。 - Drise
显示剩余9条评论
4个回答

4

尼克,解决方法就是你得知道hName已经由该类的用户(Coleman博士)分配过了。你只需要将字符串复制到字符数组中即可。

简单地说:

void Student::getHouse(char *hName)
{
  strcpy(hName, m_sHouse);
}

当然,这是简单的答案...感谢你伙计。其他答案也是正确的,只是没有遵循Coleman博士给定的特定参数...不过话说回来,我没有具体说明。几个小时后见。 - Nick

3
你正在分配新的内存并将其赋值给一个本地变量。请修改你的函数:
 void Student::getHouse(char **hName)
 {
     if (m_sHouse != NULL)
     {
        *hName = new char[strlen(m_sHouse)+1];
        strcpy(*hName, m_sHouse);
     }
 }

这将改变传递给您函数的参数所指向的地址,而不是它的副本。


我知道这个方法可以运行,但是我的老师在命名/定义类函数时给了我们非常具体的要求,因为他使用自己的主函数进行评分。他告诉我们要特别使用函数原型(如果这是一个类函数,那么它是否称为函数原型我不确定)void getName(char *mName, char *wName);,所以我不能创建指向指针的指针。 - Nick

2
指针hnamehouse的副本(您传递给getHouse的指针)。在该函数内部更改hname,但是您没有更改原始的house!要更改它,您应该返回分配的内存:
char *Student::getHouse()
{
    char *hame = NULL;
    if (m_sHouse != NULL)
    {
        hName = new char[strlen(m_sHouse)+1];
        strcpy(hName, m_sHouse);
    }
    return hname;
}

然后

house = student.getHouse();

或者给这个变量一个指针,以便它可以被改变:

void Student::getHouse(char **hName)
{
    if (m_sHouse != NULL && hname != NULL)
    {
        *hName = new char[strlen(m_sHouse)+1];
        strcpy(*hName, m_sHouse);
    }
}

然后

student.getHouse(&house);

同样地,您可以引用house变量:
void Student::getHouse(char *&hName)
{
    if (m_sHouse != NULL)
    {
        hName = new char[strlen(m_sHouse)+1];
        strcpy(hName, m_sHouse);
    }
}

然后

student.getHouse(house);

更好的解决方案是使用std::string

1
void Student::getHouse(char *hName)
{
     if (m_sHouse != NULL)
     {
        hName = new char[strlen(m_sHouse)+1];
        strcpy(hName, m_sHouse);
     }
 }

这只修改了一个指向hName的副本,而不会修改原始指针。要修改它,您需要传递指向指针的指针:

void Student::getHouse(char **hName)
{
     if (m_sHouse != NULL)
     {
        *hName = new char[strlen(m_sHouse)+1];
        strcpy(*hName, m_sHouse);
     }
 }

然后像这样调用您的函数:

student.getHouse(&house);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接