【问题标题】:C++ memcpy/strcpy of char pointer to class member char pointerC++ memcpy/strcpy 的 char 指针指向类成员 char 指针
【发布时间】:2021-08-11 06:21:14
【问题描述】:

我有一个自定义类,我们称它为“学生”和一个主方法。我正在实例化类,只想输出类的内容。

我的程序崩溃了:Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

实际代码

学生.h

#ifndef PROG2_STUDENT_H
#define PROG2_STUDENT_H

#include <iostream>

class Student
{
private:
    char *name;

    char *firstName;

    unsigned matriculationNumber;

    unsigned semester;

public:
    Student(char *name, char *firstName, unsigned matriculationNumber, unsigned semester);

    ~Student();

    friend std::ostream &operator<<(std::ostream &ostream, const Student &student);
private:
};

#endif

学生.cpp

#include <cstring>
#include "Student.h"

Student::Student(char *name, char *firstName, unsigned matriculationNumber, unsigned semester)
{
    std::strcpy(this->name, name);
    std::strcpy(this->firstName, firstName);

    this->matriculationNumber = matriculationNumber;
    this->semester            = semester;
}

Student::~Student()
{
    delete[] this->name;
    delete[] this->firstName;
}

std::ostream &operator<<(std::ostream &stream, const Student &input)
{
    stream << input.name << ", " << input.firstName << ": "
           << input.semester << " Semester, MA " << input.matriculationNumber;

    return stream;
}

和我的主要

#include <iostream>
#include "StudentPackage/Collection/StudentCollection.h"

int main()
{
    Student studentOne((char *)"Testerson", (char *)"Test", 12345, 2);
    std::cout << studentOne << std::endl;

    return 0;
}

我尝试过的

我尝试了几件事,包括 memcpy。但是使用 memcpy 我无法正确检测 char 数组的大小。

当我将 Student 构造函数更改为以下内容时,我遇到了析构函数中的删除/释放问题。我想,这无论如何都不是正确的方法,但是这种情况正在发生,因为输入变量的范围在调用类析构函数之前就被破坏了,对吗?

Student::Student(char *name, char *firstName, unsigned matriculationNumber, unsigned semester)
{
    this->name      = name;
    this->firstName = firstName;

    this->matriculationNumber = matriculationNumber;
    this->semester            = semester;
}

问题

  1. 如何正确地从构造函数复制 char 数组(名称到 this->name)?
  2. 如何正确地从构造函数复制 char 数组(firstName 到 this->firstName)?

【问题讨论】:

  • 你忘记分配内存了。
  • 参数应该是const char*,而不是char*。 (我怀疑您遇到了编译错误,但将其修复在错误的位置。)
  • 1) 即使std::strcpy 分配了内存,你也不应该在new T[n] 没有获得的任何东西上使用delete[]。 2) 使用std::string
  • 但是为什么是 (const char*)?如果我想实现类似changeName(char* newName) 的方法怎么办?也可以声明const char* newName 吗?
  • @Evg 我很想使用std::string,但这是我教授的指令^^我必须围绕它进行构建。但是你对new T[n] 意味着什么?为什么我在这里需要new 运算符?

标签: c++ arrays pointers strcpy char-pointer


【解决方案1】:

std::strcpy 不分配内存。因此,您的程序正在将输入复制到一个“垃圾”地址,该地址发生在您的 Student 对象所在的内存区域中。结果,您会遇到段违规,这不足为奇。有两种解决方案:

  • 一种“C 风格”的方式 - 手动分配内存(例如 auto n = std::strlen(name); this-&gt;name = new char[n + 1]; std::strcpy(this-&gt;name, name);),但是您需要在析构函数中手动删除它(例如 delete name;)。顺便说一句,n + 1 因为您还需要空终止符的空间,strlen 结果不包括它。
  • 更好、更“C++”的方式——使用std::string(即,将name成员变量声明为std::string)。然后你可以做一个分配:this-&gt;name = name;,不需要手动内存管理 - std::string 会照顾。
  • (代码风格) 也建议对成员变量使用一些前缀或后缀,例如m_name(更多“微软”风格),或name_ - 更多“谷歌”风格,以避免那些不必要的this-&gt; .

【讨论】:

    猜你喜欢
    • 2021-11-26
    • 2018-04-05
    • 2021-01-26
    • 2017-03-30
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2012-03-19
    • 2016-11-13
    相关资源
    最近更新 更多