Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a simple program that process strings from a file into arbitrary class Student (provided below) and appends it to self-written container ArraySequence. When error almost always occurs on marked line (marked with *****).

Class Student:

class Student {
public:
    int year;
    std::string name;
    std::string surname;
    Student(int _year, std::string _name, std::string _surname) {
        this->year = _year;
        this->name = _name;
        this->surname = _surname;
    }
    Student(const Student& s) {
        this->year = s.year;
        this->name = s.name;
        this->surname = s.surname;
    }
    Student& operator=(const Student& s) {
        this->year = s.year;
        this->name = s.name;
        this->surname = s.surname;
        return *this;
    }
    bool operator==(const Student& s) const {
        if (this->year == s.year && this->name == s.name && this->surname == s.surname)
            return true;
        return false;
    }
};

main:

int main() {
    std::ifstream data("filename");
    std::string buffer;
    ArraySequence<Student>* entities = new ArraySequence<Student>;

    getline(data, buffer, '
');
    while (buffer.size() != 0) {
        std::cout << buffer << std::endl;
        int len = static_cast<int>(buffer.find(" "));
        std::string surname = buffer.substr(0, len);
        buffer = buffer.substr(len + 1);
        len = static_cast<int>(buffer.find(" "));
        std::string name = buffer.substr(0, len);
        int year = std::stoi(buffer.substr(len + 1));
        Student b(year, name, surname);
        entities->append(b); *****
        getline(data, buffer, '
');
    }

    std::cout << count << std::endl;

Append:

template <typename T>
void ArraySequence<T>::append(const T& item) {
    ISequence<T>::length++;
    if (!(ISequence<T>::length - 1)) {
        data = (T*)malloc(sizeof(T));
    }
    else {
        data = (T*)realloc(data, sizeof(T) * ISequence<T>::length);
    }
    *(data + ISequence<T>::length - 1) = item;
}

Errors: Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT); Thread 1: EXC_BAD_ACCESS (code=1, address=0x3);

Sometimes it would just work, but other times it crashes with errors.

I'm using Xcode 11.1

In Thread 1 it says that problem with operator= of Student on the line c++ this->surname = s.surname;

What can I do in a situation like this? Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
200 views
Welcome To Ask or Share your Answers For Others

1 Answer

T consists of a non-trivial type (Student contains std::string, plus non-trivial copy/ assignment and destructor), using malloc and realloc will not work correctly.

malloc and realloc do not create viable objects. They only allocate memory. Your program likely crashes due to these invalid Student objects.

The easiest solution is to rewrite ArraySequence<T>::append to only use new[] and delete[], not malloc and realloc.

Note: malloc can be used when using placement-new, but you were not using malloc for this purpose.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...