Click here to Skip to main content
15,907,687 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello there. I got my class Error. For some reason VS:Community 2017 gives me an error.

HEAP CORRUPTION DETECTED: after Normal block (#149) at 0x00000282A99E0DE0.
CRT detected that the application wrote to memory after end of heap buffer


I've tried to change my code as much as I could and I can't see what's causing the problem.

Here's my code.
Error.h
// compilation safegaurds
#ifndef ICT_ERROR_H_
#define	ICT_ERROR_H_

#include <iostream>
namespace ict {
   class Error {
      char* m_message;
   public:
   // constructors
	   //Sets the m_message member variable to nullptr.
	   Error();
	   //Sets the m_message member variable to nullptr and then uses the message() setter member function to set the error message to the errorMessage argument.
	   Error(const char* errorMessage);
	   //A deleted copy constructor to prevent an Error object to be copied.
	   Error(const Error& em) = delete; //no implementation needed
   // destructor

   // deleted constructor and operator=
	   //A deleted assignment operator overload to prevent an Error object to be assigned to another.
	   Error& operator=(const Error& em) = delete;//no implementation needed
   // operator= for c-style strings
	   void operator=(const char* errorMessage);
   // methods
	   virtual ~Error(){ delete [] m_message; m_message = nullptr;};
	   void clear();
	   bool isClear()const;
	   void message(const char* value);
	   operator const char*() const;
	   operator bool()const;
   // cast overloads
	   friend std::ostream& operator<<(std::ostream& ostr, const Error& em);
   };
   // operator << overload prototype for cout
 
   std::ostream& operator<<(std::ostream& ostr, const Error& em);
}
#endif //ICT_ERROR_H_


Error.cpp

#define _CRT_SECURE_NO_WARNINGS 

#include "Error.h"
#include <iostream>
#include <cstring>

namespace ict{
	Error::Error() {
		m_message = nullptr;
	}

	Error::Error(const char* errorMessage) {
		m_message = nullptr;
		message(errorMessage);
	}

	//have a look
	void Error::operator=(const char* errorMessage) {
		clear();//dealloc m_message
		message(errorMessage);
	}

	void Error::clear() {
		delete[] m_message;
		m_message = nullptr;

	}


	bool Error::isClear()const {
		bool clear = false;
		if (m_message == nullptr) {
			clear = true;
		}
		return clear;
	}

	void Error::message(const char* value) {
		//clear();//dealloc m_message
		delete[] m_message;
		m_message = new char[strlen(value + 1)];
		strcpy(m_message, value);
	}

	Error::operator const char*() const {
		return m_message;
	}

	Error::operator bool()const {
		return isClear();
	}

	std::ostream& operator<<(std::ostream& ostr, const Error& em) {
		if (em.isClear()) {
			//nothing
		}
		else {
			ostr << em.m_message;
		}

		return ostr;
	}

}//namespace ict


Main.cpp

#include <iostream>
#include "Error.h"
using namespace std;
using namespace ict;
int main(){
  Error T("Testing Error Message");
  Error e;
  bool ok = true;
  int pc = 1;
  cout << T << endl << e << endl << "isClear(): " << (e.isClear() ? "Passed!" : "failed!") << endl;
  if (!e.isClear()) ok = false;
  for (int i = 0; i < 10000000; i++){
    e = "Some error message that is really long long  long  long  long  long  long  long"
       " long  long  long  long  long  long  long  long  long  long  long  long  long"
       " long  long  long  long  long  long  long  long  long  long  long  long  long"
       " long  long  long  long  long  long  long  long  long  long  long  long  long"
       " long  long  long  long  long  long  long  long  long  long  long  long  long"
       " long  long  long  long  long  long  long  long  long  long  long  long  long"
       ;
    if (i % 100000 == 0) cout << "\r" << pc++ << "%";
  }
  cout << endl << e << endl << "isClear(): " << (e ? "Failed!" : "Passed!") << endl;
  if (e) ok = false;
  e.message("Short Error Message");
  cout << e << " is the same as " << (const char*)e << endl << "isClear(): " << (e.isClear() ? "Failed!" : "Passed!") << endl;
  e.clear();
  cout << "Nothing here: >" << e << "<" << endl << "isClear(): " << (e.isClear() ? "Passed!" : "Failed!") << endl;
  if (!e) ok = false;
  cout << (ok ? "All tests passed!" : "Failed!") << endl;
  return 0;
}


What I have tried:

I've tried to compile the same code in Linux terminal with g++ and it works there as expected! So, I assume I got a memory leak some where. Could someone please point me where to look?

Linux terminal output:
Testing Error Message

isClear(): Passed!
100%
Some error message that is really long long  long  long  long  long  long  long long  long  long  long  long  long  long  long  long  long  long  long  long long  long  long  long  long  long  long  long  long  long  long  long  long long  long  long  long  long  long  long  long  long  long  long  long  long long  long  long  long  long  long  long  long  long  long  long  long  long long  long  long  long  long  long  long  long  long  long  long  long  long
isClear(): Passed!
Short Error Message is the same as Short Error Message
isClear(): Passed!
Nothing here: ><
isClear(): Passed!
All tests passed!
Posted
Updated 20-Mar-17 3:25am

1 solution

The error is here:
m_message = new char[strlen(value + 1)];
That will allocate two characters less than required (random size when the passed string is empty).

It must be:
m_message = new char[strlen(value) + 1];

The error is also present with G++ builds but not detected.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900