Member 13069821 Ответов: 1

C++ CRT обнаружен VS: сообщество


Привет. Я получил свою классную ошибку. Почему-то Против:Сообщество 2017 это дает мне ошибку.

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


Я пытался изменить свой код так сильно, как только мог, и не могу понять, в чем причина проблемы.

Вот мой код.
Ошибка.ч
// 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;
}


Что я уже пробовал:

Я пытался скомпилировать тот же код в терминале Linux с помощью g++, и он работает там, как и ожидалось! Итак, я предполагаю, что у меня где-то произошла утечка памяти. Не мог бы кто-нибудь указать мне, где искать?

Выходной терминал Линукс :
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!

1 Ответов

Рейтинг:
1

Jochen Arndt

Ошибка здесь:

m_message = new char[strlen(value + 1)];
Это выделит два символа меньше, чем требуется (случайный размер, когда переданная строка пуста).

Так и должно быть:
m_message = new char[strlen(value) + 1];

Эта ошибка также присутствует в сборках G++, но не обнаружена.