Search code examples
c++arrayspointersstrcpychar-pointer

C++ memcpy/strcpy of char pointer to class member char pointer


i have a custom class, let's call it "Student" and a main method. I'm instanciating the class, and just want to output the content of the class.

My programm crashes with a: Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Actual Code

Student.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

Student.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;
}

and my main

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

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

    return 0;
}

What i have tried

I have tried several things, including memcpy. But with memcpy I'm not able to detect the size of the char array correctly.

When i change the Student Constructor to the following, i get problems with the delete/free in the destructor. I guess, this isn't the correct way anyway, but this is happening, because the scope of the input variables are destroyed before the class destructor is called, correct?

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

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

Question

  1. How can i correctly copy the char array from constructor (name to this->name)?
  2. How can i correctly copy the char array from constructor (firstName to this->firstName)?

Solution

  • std::strcpy does not allocate memory. So your program is copying input to a "garbage" address that is occurred in the memory area where your Student object is placed. And as result no surprise that you are getting segment violation as result. There are two solutions:

    • a "C-style" way - allocate memory manually (i.e. like auto n = std::strlen(name); this->name = new char[n + 1]; std::strcpy(this->name, name);), but then you need to delete it manually (i.e. delete name;) in the destructor. btw, n + 1 because you also need room for the null-terminator, strlen result does not include it.
    • much better and more "C++" way - use std::string (i.e. declate name member variable as std::string). Then you just can do an asignment: this->name = name;, and no need manual memory management - std::string will take care.
    • (Code style) Also recommend to use some prefix or postfix for member variables, i.e. like m_name(more "Microsoft" style), or name_ - more "Google" style, to avoid those unnecessary this->.