【问题标题】:Problem with dynamic-memory-allocation while using constructors to a class对类使用构造函数时出现动态内存分配问题
【发布时间】:2020-12-24 13:14:07
【问题描述】:

我正在学习面向对象编程的概念

从动态内存分配入手,发现这段代码有问题。 我在这段代码中找不到问题,在我看来一切都很好

#include <iostream>

using namespace std;
class Team
{
    private:
    char *name;
    char stadium[20];
    char city[20];
    public:
    Team(const char *i=" ",const char *stadium=" ",const char *city=" ")
    {
        name=new char [strlen(i)];
        strcpy(name,i);
        strcpy(this->stadium,stadium);
        strcpy(this->city,city);
    }
  const char *getName() {
  return name;
  }
  const char *getCity() {
  return city;
  }
  const char *getStadium() {
  return stadium;
  }
  void setName(char *name) {
  strcpy(this->name, name);
  }
  ~Team() {
      delite [] name;
  }
};

};
int main()
{
  Team *e1 = new Team("Real Madrid", "Madrid", "Santiago Bernabeu");
  Team *e2 = new Team(*e1);
  cout << e1->getName();
  cout << "-";
  cout << e2->getName();
  e1->setName("Barselona");
  cout << e1->getName();
  cout << "-";
  cout << e2->getName();
  delete e1;
  delete e2;
   
   return 0;
}

我希望解决这个问题超过 3 个小时......但没有找到任何东西,我知道这可能不是我需要寻找解决方案的方式。但我厌倦了试图解决这个问题。

我遇到的一些错误

main.cpp: In constructor ‘Team::Team(const char*, const char*, const char*)’:
main.cpp:13:24: error: ‘strlen’ was not declared in this scope
         name=new char [strlen(*i)];
                        ^~~~~~
main.cpp:13:24: note: suggested alternative: ‘mbrlen’
         name=new char [strlen(*i)];
                        ^~~~~~
                        mbrlen
main.cpp:14:9: error: ‘strcpy’ was not declared in this scope
         strcpy(name,i);
         ^~~~~~
main.cpp:14:9: note: suggested alternative: ‘strtoq’
         strcpy(name,i);
         ^~~~~~
         strtoq

我试过这段代码

#include<iostream>
#include<cstring>
using namespace std;
class Team {
private:
  char *name;
  char city[20];
  char stadion[30];
public:
  Team(char *name = "", char *city = "", char *stadion = "") {
  this->name = new char[20];
  strcpy(this->name, name);
  strcpy(this->city, city);
  strcpy(this->stadion, stadion);
  }
  Team(const Team &e) {
  strcpy(name, e.name);
  strcpy(city, e.city);
  strcpy(stadion, e.stadion);
  }
  const char *getName() {
  return name;
  }
  const char *getCity() {
  return city;
  }
  const char *getStadion() {
  return stadion;
  }
  void setName(char *name) {
  strcpy(this->name, name);
  }
  ~Team() {
     // delite [] name;
  }
};
int main() {
  Team *e1 = new Team("Real Madrid", "Madrid", "Santiago Bernabeu");
  Team *e2 = new Team(*e1);
  cout << e1->getName();
  cout << "-";
  cout << e2->getName();
  e1->setName("Barselona");
  cout << e1->getName();
  cout << "-";
  cout << e2->getName();
  delete e1;
  delete e2;
  return 0;
}

得到这个错误

main.cpp:44:26: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]                                                   
Segmentation fault (core dumped)

【问题讨论】:

  • 您能否添加错误消息以及您尝试过的一些信息?
  • 我现在会编辑帖子,不用担心:)
  • std::string 有什么问题?如果您坚持为字符串手动分配内存,请注意strlen(i)(不是strlen(*i))不包括空终止符。 delite [] name; 也不是有效的 C++
  • 已修复但仍无法正常工作,问题是我正在使用动态分配的参数在动态内存中创建对象吗?

标签: c++ oop dynamic-memory-allocation


【解决方案1】:

我更正了您代码中的一些拼写错误,修改了 class Team 的复制构造函数,它在我的 PC 上运行良好。

class Team
{
private:
    char* name;
    char stadium[20];
    char city[20];
public:
    Team(const char* i = " ", const char* stadium = " ", const char* city = " ")
    {
        name = new char[strlen(i) + 1];  // +1 for null-terminate
        strcpy(name, i);
        strcpy(this->stadium, stadium);
        strcpy(this->city, city);
    }
    // allocating memory for Team::name needed, but I delegated it to above constructor.
    Team(const Team& e) :Team(e.name, e.stadium, e.city) {
        // empty
    }
    const char* getName() {
        return name;
    }
    const char* getCity() {
        return city;
    }
    const char* getStadium() {
        return stadium;
    }
    void setName(const char* name) {  // must be const char*. Not char*!!
        strcpy(this->name, name);
    }
    ~Team() noexcept {
        if(name)        
            delete[] name;   // delete[] name, NOT delite
    }
};

这里是编写 C++ 类的首选方式。 正如一些 cmets 已经告诉过的,比起char*,更喜欢使用std::string。我知道可能很难习惯 C++ 类,但相信我,std::stringchar* 好得多。使用std::string,不需要自己分配内存,也不需要编写额外的拷贝构造函数和析构函数。

#include <string>

using std::string;

class Team
{
public:
    Team(void) = default;
    explicit Team(const string& name, const string& stadium, const string& city)
        :name_(name), stadium_(stadium), city_(city) {}

    void setName(const string& new_name) { name_ = new_name; }
    string getName(void) const { return name_; }
    string getCity(void) const { return city_; }
    string getStadium(void) const { return stadium_; }
private:
    string name_;
    string stadium_;
    string city_;
};

【讨论】:

  • 我试过了,但还是不行……code error: ‘strlen’ was not declared in this scope name = new char[strlen(i) + 1]; // +1 for null-terminate main.cpp:15:9: error: ‘strcpy’ was not declared in this scope strcpy(name, i);
  • @World 您应该在 C++ 中包含 &lt;cstring&gt; 以使用 strcpy()strlen()
  • 是的 .. 这就是问题所在... 没关系 ty 很多脑大的男孩 :D
  • 迂腐点 - 将字符串复制到字符缓冲区时,应该真正使用 strncpystrcpy_s。 (体育场和城市)。此外,如果您有裸指针,则需要一个默认构造函数将其初始化为nullptr,或将其声明为deleted
  • 我还建议对构造函数使用右值引用,这样您就可以使用char-const* 字符串创建一个实例。
【解决方案2】:

在主文件中添加#include &lt;cstring&gt;: C++

#include <iostream>
using namespace std;
#include<cstring>  // Add this in your code

在您的主文件中:

int main() {
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 2021-07-16
    • 2021-11-29
    • 2023-02-02
    • 2015-03-12
    • 2018-04-13
    • 1970-01-01
    相关资源
    最近更新 更多