【问题标题】:Memory Heap and Leak Summary on ValgrindValgrind 上的内存堆和泄漏总结
【发布时间】:2022-01-13 16:58:52
【问题描述】:

我们学校的提交都是通过矩阵使用 valgrind 的,它逐行检查输出。但是,在提交时,我收到“检测到内存错误”。

编译结果:

Success! No errors or warnings...

执行:

Script started, file is student_output.txt
Script started, file is student_output.txt
==110143== Memcheck, a memory error detector
==110143== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==110143== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==110143== Command: ms
==110143==
Loading Data
Library Application:

输入数据时:

Publication Title: e
==111103== Conditional jump or move depends on uninitialised value(s)
==111103==    at 0x404318: sdds::LibApp::search(int, char) (LibApp.cpp:145)
==111103==    by 0x404ABC: sdds::LibApp::removePublication() (LibApp.cpp:329)
==111103==    by 0x404DC1: sdds::LibApp::run() (LibApp.cpp:415)
==111103==    by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==111103==    by 0x405084: main (LibAppMain_prof.cpp:20)
==111103==

其他信息

我在添加出版物时也遇到了错误(使用 newPublication() 函数),它位于下面的同一文件中。

==140314== Use of uninitialised value of size 8
==140314==    at 0x404926: sdds::LibApp::newPublication() (LibApp.cpp:282)
==140314==    by 0x404DAA: sdds::LibApp::run() (LibApp.cpp:411)
==140314==    by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==140314==    by 0x405084: main (LibAppMain_prof.cpp:20)
==140314==
==140314== Use of uninitialised value of size 8
==140314==    at 0x40493F: sdds::LibApp::newPublication() (LibApp.cpp:284)
==140314==    by 0x404DAA: sdds::LibApp::run() (LibApp.cpp:411)
==140314==    by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==140314==    by 0x405084: main (LibAppMain_prof.cpp:20)
==140314==

文件发布在下面。

LibApp.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <fstream>
#include <cstring>
#include <iomanip>
#include "LibApp.h"
#include "Book.h"
#include "PublicationSelector.h"

namespace sdds {

int NOLP=0;
int LLRN=0;

      bool LibApp::confirm(const char* message)
      {
         Menu conf(message);
         conf<<"Yes";  
         int t_return = conf.run();

         if(t_return) return true;

          return false;

      }

      LibApp::LibApp(const char filename[256])
      {  

         
         m_mainMenu << "Add New Publication" 
         << "Remove Publication" 
         << "Checkout publication from library"
         <<"Return publication to library";
         m_exitMenu << "Save changes and exit" << "Cancel and go back to the main menu";

         strcpy(m_filename, filename);
        

         m_publicationMenu << "Book" << "Publication" ;

         load();
      }

      LibApp::~LibApp()
      {

         for (int i = 0; i< NOLP ; i++) {
            delete PPA[i];
         }
      }

      void LibApp::load(){

   
         std::cout<<"Loading Data\n";
         
         std::ifstream infile(m_filename);
         char type{};
         
         for (int i = 0; infile ; i++) {
            infile >> type;
            infile.ignore();


            
            if (infile) {
            
               if (type == 'P')
                  PPA[i] = new Publication;
               else if (type == 'B')
                  PPA[i] = new Book;
               else std::cout<<"no data\n";

               if (PPA[i] && i < SDDS_LIBRARY_CAPACITY ) {

                  infile >> *PPA[i];

                  LLRN=PPA[i]->getRef();

                  NOLP++;



               }

            
            }
         }
      
      }  
      
      
      
      void LibApp::save(){
         std::cout<<"Saving Data\n";

    
         std::ofstream outfile(m_filename);
       
         
         for (int i = 0; i < NOLP; i++) {
            
            if (PPA[i]->getRef()!=0) {
            
               outfile << *PPA[i] << std::endl;

               
            
            }
         }      
         

      
      }   

      
      void prnPub(Publication* p[], int size, int ref) {
         int i;
         for (i = 0; i < size; i++) {
            if (ref == p[i]->getRef()) {
               std::cout << *p[i] << std::endl;
               i = size; 
            }
         }
      }

      int LibApp::search(int option,char type){
         
       
         

         PublicationSelector ps("Select one of the following found matches:", 15);

         std::cout<<"Publication Title: ";

         char title[256];

         std::cin.getline(title,256);


         if(option==1)
         {
            for (int i = 0; i< NOLP; i++) {
                     
                     if (strstr(*PPA[i],title) && PPA[i]->getRef()!=0 && type==PPA[i]->type())
                        ps << PPA[i]; 
            }
         }
         else if(option==2)
         {
            for (int i = 0; i< NOLP; i++) {
                     
                     if (strstr(*PPA[i],title) && !PPA[i]->onLoan() && PPA[i]->getRef()!=0 && type==PPA[i]->type())
                        ps << PPA[i]; 
            }
         }
         else if(option==3)
         {
            for (int i = 0; i< NOLP; i++) {
                     
                     if (strstr(*PPA[i],title) && PPA[i]->onLoan() && PPA[i]->getRef()!=0 && type==PPA[i]->type())
                        ps << PPA[i]; 
            }
         }


         int ref = 0;
  
         if (ps) {
            ps.sort(); 
            ref = ps.run(); 
            if (ref) {
               
               prnPub(PPA, NOLP , ref);
            }
            else {
               std::cout << "Aborted!\n";
            }
         }
         else {
            std::cout << "No matches to found!" << std::endl;
         }


         return ref;

   
      
      }   
      
      void LibApp::returnPub()  
      {
        
         std::cout<<"Return publication to the library\n";
         int i=m_publicationMenu.run();
         

         char type; 

         if(i==1) type='B';
         else type='P';

         int ref=search(3,type);

         
         if(ref!=0 && confirm("Returning publication?"))
         {
            Date date=getPub(ref)->checkoutDate();

            Date today;

            int days=today-date;
            days-=15;

           


            if(days>0)
            {
               
               std::cout << std::fixed;
               std::cout << std::setprecision(2);
               std::cout<<"Please pay $"<<float(days)*(0.5)<<" penalty for being "<<days<<" days late!\n";
            }

            getPub(ref)->set(0);
            std::cout<<"Publication returned\n";
            m_changed=true;

         }



      }

      void LibApp::newPublication()
      {  

         

         if( NOLP >= SDDS_LIBRARY_CAPACITY ) 
         {
            std::cout<<"Library is at its maximum capacity!\n";
            return;
         }

         std::cout<<"Adding new publication to library\n";

         int i=m_publicationMenu.run();

         Publication *p=nullptr;

         if(i==0)
         {  std::cout<<"Aborted!\n";
            return;
         }
         else if(i==1)
         {
            
            p = new Book;
            std::cin >> *p;
         }
         else if( i==2 )
         {
            p = new Publication;
            std::cin >> *p;
         }

         if(std::cin.fail())
         {
            std::cout<<"\nAborted!\n";
            exit(0);
         }


         if(confirm("Add this publication to library?"))
         {
            m_changed = true;

            PPA[NOLP]=p;

            LLRN=PPA[NOLP]->getRef();

            NOLP++;

            std::cout<<"Publication added\n";
         }

         if( !*p )
         {
            std::cout<<"Failed to add publication!\n";
            delete p;
         }

      }

      
      Publication* LibApp::getPub(int libRef)
      {
         for(int i=0;i<NOLP;i++)
         {
            if(libRef==PPA[i]->getRef()) return PPA[i];
         }

         return nullptr;

      }

      void LibApp::removePublication()
      {
         //std::cout<<;

         
            std::cout<<"Removing publication from the library\n";


         int i=m_publicationMenu.run();


         char type; 

         if(i==1) type='B';
         else 
         {  
            type='P';
         }
         int ref=search(1,type);

         
   
         if(ref!=0 && confirm("Remove this publication from the library?"))
         {
            m_changed = true;

            getPub(ref)->setRef(0);



            std::cout<<"Publication removed\n";
         }
         
      }

      void LibApp::checkOutPub()
      {  

         std::cout<<"Checkout publication from the library\n";
         int i=m_publicationMenu.run();
         char type; 

         if(i==1) type='B';
         else type='P';

         int ref=search(2,type);
         
         if(ref!=0 && confirm("Check out publication?"))
         {
            m_changed = true;

            int mn;

            std::cout << "Enter Membership Number: ";

            while (1)
            {              
               

               std::cin>>mn;

               if(mn > 9999 && mn <= 99999 ) break;

               std::cout<<"Invalid membership number, try again: ";
            }

            getPub(ref)->set(mn);

            std::cout<<"Publication checked out\n";
         }


      }



      LibApp::LibApp()
      {
         m_mainMenu << "Add New Publication" 
         << "Remove Publication" 
         << "Checkout publication from library"
         <<"Return publication to library";

         m_exitMenu << "Save changes and exit" << "Cancel and go back to the main menu";

         load();

      }


      

      void LibApp::run()
      {
         while(1)
         {  
            int option =  m_mainMenu.run();

            if( option == 1 )
            {
               newPublication();
            }
            else if( option == 2 ) 
            {
               removePublication();
            }
   

     else if( option == 3 )
        {
           checkOutPub();
        }
        else if( option == 4 )
        {
           returnPub();
        }
        else if( option == 0 )
        {
           if(m_changed)
           {
              
              int opn = m_exitMenu.run();

              if( opn == 1 )
              {
                 save();
                 break;
              }
              else if( opn == 2 )
              {
                 ;
              }
              else if( opn == 0)
              {  
                 if(confirm("This will discard all the changes are you sure?"))
                    break;
              }

           }
           else break;


        }

        std::cout<<std::endl;

        
     }



     std::cout<<std::endl;
     std::cout<<"-------------------------------------------\n";
     std::cout<<"Thanks for using Seneca Library Application\n";



      }

}

请帮帮我。我今天提交的内容是我知道问题是什么。

【问题讨论】:

  • Stack Overflow 不是免费的作业帮助服务。

标签: c++ memory memory-leaks valgrind


【解决方案1】:

就像错误信息说的那样:

Conditional jump or move depends on uninitialised value(s)
==111103==    at 0x404318: sdds::LibApp::search(int, char) (LibApp.cpp:145)

在 LibApp.cpp 的第 145 行有一个 if 语句(或逻辑上等同于 if 语句的东西),它根据从未初始化为任何值的变量决定采用哪条路径;因此,该 if-test 的行为是未定义的(即 if 可以采用任何一种方式,具体取决于当时该变量的内存位置发生的任意数据)。

因此,您需要查看第 145 行 if-test 中存在的变量,以确定哪些变量没有被预先设置,然后通过确保它们首先被设置来修复错误.

如有必要,您可以添加临时 if-tests 以激发 valgrind 为您提供更多结果:

if (some_suspect_var != 0) fprintf(stderr, “Yea\n”);
else fprintf(stderr, “Nay\n”);

…那么如果你在那个 if 行上得到一个 valgrind 错误,你就知道 some_suspect_var 在那一点上是未初始化的。

【讨论】:

  • if 语句不是问题。出于某种原因,我的内存没有被动态分配和释放。有人能解决这个问题吗?
  • 解决问题的唯一方法是编译/运行/测试/诊断/重复直到您了解故障,此时您也将了解如何修复它。如果您发布的代码可以由其他人编译,其他人可能会为您执行此操作,但由于它只是部分列表,其他人将无法编译和运行它,这意味着它取决于您弄清楚。
猜你喜欢
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 2016-03-15
  • 2014-04-09
相关资源
最近更新 更多