Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. Double Bug

Double Bug

Scheduled Pinned Locked Moved Clever Code
helpannouncement
15 Posts 7 Posters 36 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Zac Howland

    That is the first bug (memory leak):

    int main()
    {
    	Stuff myStuff;
    	char* pTemp = getName();
    	myStuff.setName(pTemp);
    	delete pTemp;
    	pTemp = getAddress();
    	myStuff.setAddress(pTemp);
    	delete pTemp;
    
    	// do a whole lot of really cool things here
    }
    

    Which should reveal the second bug ...

    If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

    B Offline
    B Offline
    Bugra Barin
    wrote on last edited by
    #6

    If you delete the char arrays right away like that, your Stuff object will have dangling pointers, and you'll have a lot of fun doing those really cool things afterwards :-)

    Z 1 Reply Last reply
    0
    • B Bugra Barin

      If you delete the char arrays right away like that, your Stuff object will have dangling pointers, and you'll have a lot of fun doing those really cool things afterwards :-)

      Z Offline
      Z Offline
      Zac Howland
      wrote on last edited by
      #7

      Exactly! The fix for both bugs looked like this:

      // class definition
      class Stuff
      {
      public:
      	Stuff() {}
      	~Stuff() {}
      
      	void setName(const char* name) {_name = name;}
      	void setAddress(const char* addr) {_address = addr;}
      private:
      	std::string _name;
      	std::string _address;
      };
      
      // usage
      // the following functions were actually part of a 3rd-party library, so they could not be changed
      char* getName()
      {
      	char* pRet = new char[20];
      	memset(pRet, 0, 20);
      	strcpy(pRet, "Charlie");
      	return pRet;
      }
      
      char* getAddress()
      {
      	char* pRet = new char[20];
      	memset(pRet, 0, 20);
      	strcpy(pRet, "United States");
      	return pRet;	
      }
      
      int main()
      {
      	Stuff myStuff;
      	char* pTemp = getName();
      	myStuff.setName(pTemp);
      	delete [] pTemp;
      	pTemp = getAddress();
      	myStuff.setAddress(pTemp);
      	delete [] pTemp;
      
      	// do some really cool stuff here
      }
      

      If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

      N J 2 Replies Last reply
      0
      • Z Zac Howland

        Exactly! The fix for both bugs looked like this:

        // class definition
        class Stuff
        {
        public:
        	Stuff() {}
        	~Stuff() {}
        
        	void setName(const char* name) {_name = name;}
        	void setAddress(const char* addr) {_address = addr;}
        private:
        	std::string _name;
        	std::string _address;
        };
        
        // usage
        // the following functions were actually part of a 3rd-party library, so they could not be changed
        char* getName()
        {
        	char* pRet = new char[20];
        	memset(pRet, 0, 20);
        	strcpy(pRet, "Charlie");
        	return pRet;
        }
        
        char* getAddress()
        {
        	char* pRet = new char[20];
        	memset(pRet, 0, 20);
        	strcpy(pRet, "United States");
        	return pRet;	
        }
        
        int main()
        {
        	Stuff myStuff;
        	char* pTemp = getName();
        	myStuff.setName(pTemp);
        	delete [] pTemp;
        	pTemp = getAddress();
        	myStuff.setAddress(pTemp);
        	delete [] pTemp;
        
        	// do some really cool stuff here
        }
        

        If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

        N Offline
        N Offline
        Nish Nishant
        wrote on last edited by
        #8

        Zac Neither of those bugs were particularly subtle. The leak was glaringly obvious. And to be accurate, there was no 2nd bug in your original code - the 2nd bug was artificially introduced as a possible bad fix to the first bug (the leak) by deleting the memory before the object that had members pointing to that memory went out of scope. Again, that's also not very subtle - pretty obvious bug there.

        Regards, Nish


        Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
        Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

        Z M 2 Replies Last reply
        0
        • Z Zac Howland

          Exactly! The fix for both bugs looked like this:

          // class definition
          class Stuff
          {
          public:
          	Stuff() {}
          	~Stuff() {}
          
          	void setName(const char* name) {_name = name;}
          	void setAddress(const char* addr) {_address = addr;}
          private:
          	std::string _name;
          	std::string _address;
          };
          
          // usage
          // the following functions were actually part of a 3rd-party library, so they could not be changed
          char* getName()
          {
          	char* pRet = new char[20];
          	memset(pRet, 0, 20);
          	strcpy(pRet, "Charlie");
          	return pRet;
          }
          
          char* getAddress()
          {
          	char* pRet = new char[20];
          	memset(pRet, 0, 20);
          	strcpy(pRet, "United States");
          	return pRet;	
          }
          
          int main()
          {
          	Stuff myStuff;
          	char* pTemp = getName();
          	myStuff.setName(pTemp);
          	delete [] pTemp;
          	pTemp = getAddress();
          	myStuff.setAddress(pTemp);
          	delete [] pTemp;
          
          	// do some really cool stuff here
          }
          

          If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

          J Offline
          J Offline
          jhwurmbach
          wrote on last edited by
          #9

          Zac Howland wrote:

          The fix for both bugs looked like this [...]

          Thats not a fix, that is proper programming technique! :-D


          "We trained hard, but it seemed that every time we were beginning to form up into teams we would be reorganised. I was to learn later in life that we tend to meet any new situation by reorganising: and a wonderful method it can be for creating the illusion of progress, while producing confusion, inefficiency and demoralisation." -- Caius Petronius, Roman Consul, 66 A.D.

          Z 1 Reply Last reply
          0
          • N Nish Nishant

            Zac Neither of those bugs were particularly subtle. The leak was glaringly obvious. And to be accurate, there was no 2nd bug in your original code - the 2nd bug was artificially introduced as a possible bad fix to the first bug (the leak) by deleting the memory before the object that had members pointing to that memory went out of scope. Again, that's also not very subtle - pretty obvious bug there.

            Regards, Nish


            Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
            Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

            Z Offline
            Z Offline
            Zac Howland
            wrote on last edited by
            #10

            Nishant Sivakumar wrote:

            Neither of those bugs were particularly subtle. The leak was glaringly obvious. And to be accurate, there was no 2nd bug in your original code - the 2nd bug was artificially introduced as a possible bad fix to the first bug (the leak) by deleting the memory before the object that had members pointing to that memory went out of scope. Again, that's also not very subtle - pretty obvious bug there.

            The leak was not so subtle. However, the memory violation was more subtle in the original code because the new was called within the 3rd party library (which only the header and a .so was available for). I just simplified the code to make it more obvious (perhaps too obvious).

            If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

            N 1 Reply Last reply
            0
            • J jhwurmbach

              Zac Howland wrote:

              The fix for both bugs looked like this [...]

              Thats not a fix, that is proper programming technique! :-D


              "We trained hard, but it seemed that every time we were beginning to form up into teams we would be reorganised. I was to learn later in life that we tend to meet any new situation by reorganising: and a wonderful method it can be for creating the illusion of progress, while producing confusion, inefficiency and demoralisation." -- Caius Petronius, Roman Consul, 66 A.D.

              Z Offline
              Z Offline
              Zac Howland
              wrote on last edited by
              #11

              jhwurmbach wrote:

              Thats not a fix, that is proper programming technique!

              Agreed; however, isn't that what most bug fixes are? ;P

              If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

              1 Reply Last reply
              0
              • Z Zac Howland

                Nishant Sivakumar wrote:

                Neither of those bugs were particularly subtle. The leak was glaringly obvious. And to be accurate, there was no 2nd bug in your original code - the 2nd bug was artificially introduced as a possible bad fix to the first bug (the leak) by deleting the memory before the object that had members pointing to that memory went out of scope. Again, that's also not very subtle - pretty obvious bug there.

                The leak was not so subtle. However, the memory violation was more subtle in the original code because the new was called within the 3rd party library (which only the header and a .so was available for). I just simplified the code to make it more obvious (perhaps too obvious).

                If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                N Offline
                N Offline
                Nish Nishant
                wrote on last edited by
                #12

                Zac Howland wrote:

                The leak was not so subtle. However, the memory violation was more subtle in the original code because the new was called within the 3rd party library (which only the header and a .so was available for). I just simplified the code to make it more obvious (perhaps too obvious).

                Ah, perhaps it was subtle in the original code. By the way, there's either a leak or a memory violation (since it's the incorrectly placed delete that caused the memory violation). Which of the two was present in your original code?

                Regards, Nish


                Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

                Z 1 Reply Last reply
                0
                • N Nish Nishant

                  Zac Howland wrote:

                  The leak was not so subtle. However, the memory violation was more subtle in the original code because the new was called within the 3rd party library (which only the header and a .so was available for). I just simplified the code to make it more obvious (perhaps too obvious).

                  Ah, perhaps it was subtle in the original code. By the way, there's either a leak or a memory violation (since it's the incorrectly placed delete that caused the memory violation). Which of the two was present in your original code?

                  Regards, Nish


                  Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                  Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

                  Z Offline
                  Z Offline
                  Zac Howland
                  wrote on last edited by
                  #13

                  The original code was using Xerces XML parser and calling XMLString::transcode (which you have to read the documentation to realize that it returns a XMLStr* or char* that must be released with XMLString::release). Since the release call was not made, there was a leak (this happened in several places all throughout the code). An object (that resided in another static library) was created and passed the name returned from this transcode function, but the destructor for the object never released any memory (it just held the 2 pointers -- this wasn't initially obvious since the object was in a completely separate library). So when I fixed the memory leak in the library I was working on, we started to see random crashes (access violations) in our simulator. Upon further investigation, the original author of the set of libraries wrote it to store only the pointers, so by fixing the memory leak, I discovered the design flaw. Thus, both were present in the original, but the leak masked the design flaw. Its much easier to see in 30 lines of code or less ... but when you are talking about 5000 lines of code between 3 libraries, its not so obvious.

                  If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                  1 Reply Last reply
                  0
                  • N Nish Nishant

                    Zac Neither of those bugs were particularly subtle. The leak was glaringly obvious. And to be accurate, there was no 2nd bug in your original code - the 2nd bug was artificially introduced as a possible bad fix to the first bug (the leak) by deleting the memory before the object that had members pointing to that memory went out of scope. Again, that's also not very subtle - pretty obvious bug there.

                    Regards, Nish


                    Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                    Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

                    M Offline
                    M Offline
                    Mr Brainley
                    wrote on last edited by
                    #14

                    Nishant Sivakumar wrote:

                    The leak was glaringly obvious.

                    Well, all this implicit copying compilers do and stuff like that, i really don't get it, so could you please explain where exactly the leak is ?

                    N 1 Reply Last reply
                    0
                    • M Mr Brainley

                      Nishant Sivakumar wrote:

                      The leak was glaringly obvious.

                      Well, all this implicit copying compilers do and stuff like that, i really don't get it, so could you please explain where exactly the leak is ?

                      N Offline
                      N Offline
                      Nish Nishant
                      wrote on last edited by
                      #15

                      Mr.Brainley wrote:

                      Well, all this implicit copying compilers do and stuff like that, i really don't get it, so could you please explain where exactly the leak is ?

                      A char array is new'd but there's no corresponding delete.

                      Regards, Nish


                      Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                      Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups