简体   繁体   中英

how can i solve valgrind memory leak error

I have 3 files in total and I get the output I want but I am getting a memory leak error when run with Valgrind.

main.cpp

#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;
}

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

Car.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();
        }
    }
}

Here is the output I want And I got it

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!   +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

But here is the memory leak error

==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)

So this is the memory leak issue I am facing can anyone please help me to solve this

When you call setInfo() you don't delete the strings you allocated in the constructor and the variables are assigned new values, the previous pointers are dangling and cannot be deleted - hence the memory leak

  1. In cpp I would suggest to use std::string , there is no need in allocating raw pointers in that case - and these memory leaks are a good lesson why.

  2. Code review wise - if you do decide to use pointers, the destructor and resetInfo() have much in common and you can use resetInfo() as part of the destructor.

Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM