diff options
author | frosch <frosch@openttd.org> | 2015-04-23 20:07:07 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2015-04-23 20:07:07 +0000 |
commit | 8ffe068c118086efd65974ad1fdacaaedd49504f (patch) | |
tree | 40b4549176867eefd6925c3eeafc079314a5db88 | |
parent | 9de0eccf7f9cae0836670865d0aae87768f30fbd (diff) | |
download | openttd-8ffe068c118086efd65974ad1fdacaaedd49504f.tar.xz |
(svn r27243) -Fix (r26816) [FS#6285]: Duplicate frees due to pool item classes not having copy constructors.
-rw-r--r-- | src/saveload/engine_sl.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index df4aa37b9..a568fead7 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -48,21 +48,39 @@ static const SaveLoad _engine_desc[] = { SLE_END() }; -static std::vector<Engine> _temp_engine; +static std::vector<Engine*> _temp_engine; + +/** + * Allocate an Engine structure, but not using the pools. + * The allocated Engine must be freed using FreeEngine; + * @return Allocated engine. + */ +static Engine* CallocEngine() +{ + uint8 *zero = CallocT<uint8>(sizeof(Engine)); + Engine *engine = new (zero) Engine(); + return engine; +} + +/** + * Deallocate an Engine constructed by CallocEngine. + * @param e Engine to free. + */ +static void FreeEngine(Engine *e) +{ + if (e != NULL) { + e->~Engine(); + free(e); + } +} Engine *GetTempDataEngine(EngineID index) { if (index < _temp_engine.size()) { - return &_temp_engine[index]; + return _temp_engine[index]; } else if (index == _temp_engine.size()) { - uint8 zero[sizeof(Engine)]; - memset(zero, 0, sizeof(zero)); - Engine *engine = new (zero) Engine(); - - /* Adding 'engine' to the vector makes a shallow copy, so we do not want to destruct 'engine' */ - _temp_engine.push_back(*engine); - - return &_temp_engine[index]; + _temp_engine.push_back(CallocEngine()); + return _temp_engine[index]; } else { NOT_REACHED(); } @@ -127,6 +145,9 @@ void CopyTempEngineData() } /* Get rid of temporary data */ + for (std::vector<Engine*>::iterator it = _temp_engine.begin(); it != _temp_engine.end(); ++it) { + FreeEngine(*it); + } _temp_engine.clear(); } |