Home > database >  how can i solve valgrind memory leak error
how can i solve valgrind memory leak error

Time:06-09

I have 3 files in total and I get the output I want but I am getting a memory leak error when compile With Valgrind (It's a tool for checking is there any memory leak in code)

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 | M |  %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

CodePudding user response:

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!

CodePudding user response:

I've had a cursory look at your code and it seems to me that you're stuck between two worlds - the old C world and the new(er) C world. If I recall correctly, the approved method in C for a null pointer is simply to use a zero (0), rather than 'nullptr' like you've got here. I'd be very suspicious of that part where you're assigning nullptr to a pointer (3, in fact). If that was dynamically allocated memory, you're doing nothing to reclaim it. Also, is there any good reason why you're using C-style character arrays rather than the standard library's strings?

  • Related