首页 > 解决方案 > C++ 缓冲区溢出(大小为 8 的无效读取)

问题描述

这是主要的测试文件,不能更改,总共有 3 个文件,不包括头文件。main.cpp、engine.cpp、ship.cpp。我也包含了我的错误的屏幕截图,但它在 ship.cpp 文件的测试的 T5 部分中无效读取大小为 8 的错误(内存泄漏)。它输出正确的答案,但显然有内存泄漏。我的错误图片

#include <iostream>
#include "Ship.h"
#include "Ship.h"
#include "Engine.h"
#include "Engine.h"

using namespace std;
using namespace sdds;

void printHeader(const char* title)
{
    char oldFill = cout.fill('-');
    cout.width(40);
    cout << "" << endl;

    cout << "|> " << title << endl;

    cout.fill('-');
    cout.width(40);
    cout << "" << endl;
    cout.fill(oldFill);
}

int main()
{
    {
        printHeader("T1: Testing Constants");

        cout << "TYPE_MAX_SIZE: " << sdds::TYPE_MAX_SIZE << endl;
        cout << "MIN_STD_POWER: " << sdds::MIN_STD_POWER << endl;
        cout << "MAX_STD_POWER: " << sdds::MAX_STD_POWER << endl;
        cout << endl;
    }

    {
        printHeader("T2: Testing Default Constructor");

        Ship invalid;
        invalid.display();
        invalid += Engine("D2", 2.1);
        cout << endl;
    }

    Engine engines[] = {
        Engine("V8", 4.4),
        Engine("V8", 5.0),
        Engine("Inline", 4.1),
        Engine("D3", 7.0),
        Engine("D0", 2.0),
        Engine("D1", 3.2),
    };

    {
        printHeader("T3: Testing Custom Constructor");
        
        Ship titanic("cruiser", engines, 6);
        titanic.display();
        cout << endl;
    }

    {
        printHeader("T4: Testing Conversion to Bool Operator");
        Ship invalid;
        Ship titanic("liner", engines, 1);

        if (invalid)
            cout << "1. Test Failed! Object should be invalid.\n";
        else
            cout << "1. Test succeeded!\n";

        if (titanic)
            cout << "2. Test succeeded!\n";
        else
            cout << "3. Test Failed! Object should be valid.\n";
        
        cout << endl;
    }

    {
        printHeader("T5: Testing += and < Operators");

        Ship titanic("liner", engines, 3);

        char type[]{ "D0" };
        while (titanic < sdds::MIN_STD_POWER)
        {
            type[1]++;
            cout << "Ship not up to standard. Required power: "
                 << sdds::MIN_STD_POWER << endl;
            titanic += Engine(type, 2.1);
        }

        titanic.display();

        if (sdds::MAX_STD_POWER < titanic)
            cout << "Too much power." << endl;
        else
            cout << "Ship doesn't exceed power regulation of: "
                 << sdds::MAX_STD_POWER << endl;
    }

    return 0;
}

这是我的 engine.cpp 文件

#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include "Engine.h"
using namespace sdds;
using namespace std;

namespace sdds {
Engine::Engine(){       // Default Empty Engine
    m_type[0] = '\0';
    m_size = 0.0;
}

Engine::Engine(const char* type, double size){  // Custom Engine
    strncpy(m_type, type, TYPE_MAX_SIZE);
    m_size = size;
}

double Engine::get() const{ // Getter for the size of the engine
    return m_size;
}

void Engine::display() const{   // Basic Display Function
    cout << m_size << " liters - " << m_type << endl;
    
}
}

这是我的 ship.cpp,错误出现在 += 重载运算符函数中。

#include <iostream>
#include <cstring>
#include "Ship.h"

using namespace std;

namespace sdds {

Ship::Ship(){           // Default Ship (empty)
    m_type = nullptr;
    m_engines = nullptr;
    m_engCnt = 0;
}

Ship::Ship(const char* type, const Engine* engines, int engCnt){  // Custom Ship
    if (type != nullptr && engines != nullptr && engCnt > 0) {
        // creating a Valid Ship
        int len = (unsigned)strlen(type);
        m_type = new char[len + 1];
        strcpy(m_type, type);
        
        m_engines = new Engine[engCnt];
        
        for (int i = 0; i < engCnt; i++) {
            m_engines[i] = engines[i];
        }
        m_engCnt = engCnt;
        
    }else{
        m_type = nullptr; // Setting Ship to Empty State
        m_engines = nullptr;
        m_engCnt = 0;
    }
}

Ship::~Ship(){
    delete[] m_engines;
    delete[] m_type;
}

Ship::operator bool() const {
    // returning true if the ship is valid (not empty)
    return m_type != nullptr;
}

Ship& Ship::operator+=(Engine e){  // THIS IS WHERE THE ERROR IS <-----------------
    if (!*this) {
        cout << "The object is not valid! Engine cannot be added!" << endl;
    }else{
        Engine* tmp = new Engine[m_engCnt + 1];
        for (int i = 0; i <= m_engCnt; i++) {
            tmp[i] = m_engines[i];
        }
        tmp[m_engCnt++] = e;
        for (int i = 0; i <= m_engCnt; i++) {
            m_engines[i] = tmp[i];
        }
    }
    return *this;

}

double Ship::calculatePower() const {       // Multiplying the Engines Size * 5 to get the power(sum of all)
    double power = 0;
    for (int i = 0; i < m_engCnt; i++) {
        power += m_engines[i].get() * 5;
    }
    return power;
}

void Ship::display()const{  // Displaying the Ship
    if (*this) {
        streamsize dp = cout.precision(); // save default precision
        cout.precision(2); // change default precision
        cout << fixed; // enable fixed
        cout << m_type << " - " << calculatePower() << endl;
        for (int i = 0; i < m_engCnt; i++) {
            m_engines[i].display(); // Engines Display function
        }
        cout.unsetf(ios::fixed); // disable fixed
        cout.precision(dp); // restore default precision
    }else{
        cout << "No available data" << endl;
    }
}
bool Ship::operator<(double power) const{       // Comparing the passed in power with the power of the ship
    if (calculatePower() < power) {
        return true;
    }else{
        return false;
    }
}

bool operator<(double power, const Ship& theShip){  // Global < overloaded operator
    if (power < theShip.calculatePower()) {
        return true;
    }else{
        return false;
    }
}
}

标签: c++

解决方案


推荐阅读