簡體   English   中英

如何解決 valgrind 內存泄漏錯誤

[英]how can i solve valgrind memory leak error

我總共有 3 個文件,我得到了我想要的輸出,但是在使用 Valgrind 運行時出現內存泄漏錯誤。

主文件

#include<iostream>
#include<iomanip>
#include "Car.h"
using namespace std;
using namespace sdds;

int main()
{
    const int num_cars = 6;
    Car carInventory[num_cars] = {
        {},
        {"suv", "volvo", "xc90"},
        {"Truck", "Ford", "F 150", 2021, 105, 55000},
        {"Sedan", "BMW", "M550i", 2022, 101, 91000},
        {"Truck", "Tesla", "Cybertruck", 2021, 102, 65000},
        {"Sedan", "BMW", "M550i"}
    };
    
    if (carInventory[2].setInfo("SUV", "Volvo", "XC90", 2019, 109, 80000).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }
    if (carInventory[1].setInfo(nullptr, "Volvo", "XC90", 2019, 109, 80000).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }
    if (carInventory[1].setInfo("SUV", nullptr, "XC90", 2019, 109, 80000).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }
    if (carInventory[1].setInfo("SUV", "Volvo", nullptr, 2019, 109, 80000).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }
    if (carInventory[1].setInfo("SUV", "Volvo", "XC90", 1934, 109, 80000).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }
    if (carInventory[1].setInfo("SUV", "Volvo", "XC90", 2019, 1, 80000).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }
    if (carInventory[1].setInfo("SUV", "Volvo", "XC90", 2019, 109, 0).isValid()) {
        cout << "Information was set correctly!" << endl;
    }
    else {
        cout << "Information was set incorrectly!" << endl;
    }

    cout << setw(60) << "----- Testing printInfo function -----" << endl << endl;
    cout << "| Type       | Brand            | Model            | Year | Code |     Price |" << endl;
    cout << "+------------+------------------+------------------+------+------+-----------+" << endl;
    carInventory[4].printInfo();
    cout << endl << endl;
    cout << setw(60) << "----- Car Inventory Information -----" << endl << endl;
    cout << "| Type       | Brand            | Model            | Year | Code |     Price |" << endl;
    cout << "+------------+------------------+------------------+------+------+-----------+" << endl;
    print(carInventory, num_cars);

    if (has_invalid(carInventory, num_cars)) {
        cout << endl;
        cout << setfill('*') << setw(60) << "*" << endl;
        cout << "*  WARNING: There are invalid data in the inventory!      *" << endl;
        cout << setfill('*') << setw(60) << "*" << endl;
    }
    if (has_similar(carInventory, num_cars)) {
        cout << endl;
        cout << setfill('+') << setw(60) << "+" << endl;
        cout << "+  WARNING: There are similar entries in the inventory!   +" << endl;
        cout << setfill('+') << setw(60) << "+" << endl;
    }
    return 0;
}

汽車.h

#ifndef SDDS_CAR_H
#define SDDS_CAR_H
namespace sdds{
    class Car{
        private:
        char *m_type;
        char *m_brand;
        char *m_model;
        int m_year;
        int m_code;
        double m_price;

        public:
        Car();
        Car(const char *type, const char *brand, const char *model, int year = 2022, int code = 100, double price = 1);
        ~Car();
        void resetInfo();

        
        Car& setInfo(const char *type, const char *brand, const char *model,int yera,int code, double price);
        void printInfo() const;
        bool isValid() const;
        bool isSimilarTo(const Car& car) const;
    };
    bool has_similar(const Car car[], const int num_cars);
    bool has_invalid(const Car car[], const int num_cars);
    void print(const Car car[], const int num_cars);
}
#endif

汽車.cpp

#include <bits/stdc++.h>
#include "Car.h"
using namespace std;
namespace sdds{
    void Car::resetInfo(){
        m_type = nullptr;
        m_brand = nullptr;
        m_model = nullptr;
        m_year = 0;
        m_code = 0;
        m_price = 0;
    }
    Car::Car(){
        resetInfo();
    }
    Car::Car(const char* type, const char* brand, const char* model, int year, int code, double price){
        if(type != nullptr && brand != nullptr && model != nullptr && year > 0 && code > 0 && price > 0){
            m_type = new char[strlen(type) + 1];
            strcpy(m_type, type);
            m_brand = new char[strlen(brand) + 1];
            strcpy(m_brand, brand);
            m_model = new char[strlen(model) + 1];
            strcpy(m_model, model);
            m_year = year;
            m_code = code;
            m_price = price;
        }
        else{
            cout<<"any time here\n";
            resetInfo();
        }
    }
    Car::~Car(){
        delete[] m_type;
        delete[] m_brand;
        delete[] m_model;
        m_type = nullptr;
        m_brand = nullptr;
        m_model = nullptr;
    }
    
    Car& Car::setInfo(const char *type,const char *brand, const char *model,int year,int code,double price){
        this->resetInfo();
        if(type == nullptr || brand == nullptr || model == nullptr || year < 1990 || code <= 99 || price <= 0){
           // this->resetInfo();
            return *this;
        }
        else{
            m_type = new char[strlen(type) + 1];
            strcpy(m_type, type);
            m_brand = new char[strlen(brand) + 1];
            strcpy(m_brand, brand);
            m_model = new char[strlen(model) + 1];
            strcpy(m_model, model);
            m_year = year;
            m_code = code;
            m_price = price;
        }
        return *this;
    }

    void Car::printInfo()const{
        //cout << "| " << m_type << setw(8) << "| " << m_brand << setw(14) << "| " << m_model << setw(9) << " | " << m_year << setw(3) << "| " << m_code << setw(4) << " | " << m_price << setw(6) << " |" << endl;
        if(m_type != nullptr && m_brand != nullptr && m_model != nullptr && m_year >= 1990 && m_code > 99 && m_price > 0){
            printf("| %-10s | %-15s  | %-15s  | %-4d | %4d |  %8.2lf |\n",m_type,m_brand,m_model,m_year,m_code,m_price);
        }
        
    }

    bool Car::isValid()const{
        //return m_type != nullptr && m_brand != nullptr && m_model != nullptr && m_year > 0 && m_code > 0 && m_price > 0;
        if(m_type != nullptr && m_brand != nullptr && m_model != nullptr && m_year >= 1990 && m_code >= 100 && m_price > 0){
            //cout<<m_type<<" "<<m_brand<<" "<<m_model<<" "<<m_year<<" "<<m_code<<" "<<m_price<<endl;
            return true;
        }
        else{
            //cout<<m_type<<" "<<m_brand<<" "<<m_model<<" "<<m_year<<" "<<m_code<<" "<<m_price<<endl;
            return false;
        }
    }

    bool Car::isSimilarTo(const Car& other)const{
            if(m_type == other.m_type && m_brand == other.m_brand && m_model == other.m_model && m_year == other.m_year){
                return true;
            }
            else{
                return false;
            }
            return false;
    }

    bool has_similar(const Car car[],const int num_cars){
        for(int i = 0; i < num_cars; i++){
            for(int j = i + 1; j < num_cars; j++){
                if(car[i].isSimilarTo(car[j])){
                    return true;
                }
            }
        }
        return false;
    }

    bool has_invalid(const Car car[], const int num_cars){
        for(int i = 0; i < num_cars; i++){
            if(!car[i].isValid()){
                return true;
            }
        }
        return false;
    }

   void print(const Car car[], const int num_cars){
        for(int i = 0; i < num_cars; i++){
            car[i].printInfo();
        }
    }
}

這是我想要的輸出,我得到了

Information was set correctly!
Information was set incorrectly!
Information was set incorrectly!
Information was set incorrectly!
Information was set incorrectly!
Information was set incorrectly!
Information was set incorrectly!
                      ----- Testing printInfo function -----

| Type       | Brand            | Model            | Year | Code |     Price |
+------------+------------------+------------------+------+------+-----------+
| Truck      | Tesla            | Cybertruck       | 2021 |  102 |  65000.00 |


                       ----- Car Inventory Information -----

| Type       | Brand            | Model            | Year | Code |     Price |
+------------+------------------+------------------+------+------+-----------+
| SUV        | Volvo            | XC90             | 2019 |  109 |  80000.00 |
| Sedan      | BMW              | M550i            | 2022 |  101 |  91000.00 |
| Truck      | Tesla            | Cybertruck       | 2021 |  102 |  65000.00 |
| Sedan      | BMW              | M550i            | 2022 |  100 |      1.00 |

************************************************************
*  WARNING: There are invalid data in the inventory!      *
************************************************************

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  WARNING: There are similar entries in the inventory!   +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

但這是內存泄漏錯誤

==86467==
==86467== HEAP SUMMARY:
==86467==     in use at exit: 32 bytes in 6 blocks
==86467==   total heap usage: 19 allocs, 13 frees, 72,806 bytes allocated
==86467==
==86467== 4 bytes in 1 blocks are definitely lost in loss record 1 of 6
==86467==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==86467==    by 0x400C2C: sdds::Car::Car(char const*, char const*, char const*, int, int, double) (Car.cpp:27)
==86467==    by 0x401229: main (main_prof.cpp:23)
==86467==
==86467== 5 bytes in 1 blocks are definitely lost in loss record 2 of 6
==86467==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==86467==    by 0x400C98: sdds::Car::Car(char const*, char const*, char const*, int, int, double) (Car.cpp:31)
==86467==    by 0x401229: main (main_prof.cpp:23)
==86467==
==86467== 5 bytes in 1 blocks are definitely lost in loss record 3 of 6
==86467==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==86467==    by 0x400C61: sdds::Car::Car(char const*, char const*, char const*, int, int, double) (Car.cpp:29)
==86467==    by 0x40126D: main (main_prof.cpp:23)
==86467==
==86467== 6 bytes in 1 blocks are definitely lost in loss record 4 of 6
==86467==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==86467==    by 0x400C61: sdds::Car::Car(char const*, char const*, char const*, int, int, double) (Car.cpp:29)
==86467==    by 0x401229: main (main_prof.cpp:23)
==86467==
==86467== 6 bytes in 1 blocks are definitely lost in loss record 5 of 6
==86467==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==86467==    by 0x400C2C: sdds::Car::Car(char const*, char const*, char const*, int, int, double) (Car.cpp:27)
==86467==    by 0x40126D: main (main_prof.cpp:23)
==86467==
==86467== 6 bytes in 1 blocks are definitely lost in loss record 6 of 6
==86467==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==86467==    by 0x400C98: sdds::Car::Car(char const*, char const*, char const*, int, int, double) (Car.cpp:31)
==86467==    by 0x40126D: main (main_prof.cpp:23)
==86467==
==86467== LEAK SUMMARY:
==86467==    definitely lost: 32 bytes in 6 blocks
==86467==    indirectly lost: 0 bytes in 0 blocks
==86467==      possibly lost: 0 bytes in 0 blocks
==86467==    still reachable: 0 bytes in 0 blocks
==86467==         suppressed: 0 bytes in 0 blocks
==86467==
==86467== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)

所以這是我面臨的內存泄漏問題,任何人都可以幫我解決這個問題

當您調用setInfo()時,您不會刪除您在構造函數中分配的字符串並且為變量分配了新值,以前的指針懸空並且無法刪除 - 因此內存泄漏

  1. 在 cpp 我建議使用std::string ,在這種情況下不需要分配原始指針 - 這些內存泄漏是一個很好的教訓。

  2. 明智的代碼審查 - 如果你決定使用指針,析構函數和resetInfo()有很多共同點,你可以使用resetInfo()作為析構函數的一部分。

祝你好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM