summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2015-04-23 20:07:07 +0000
committerfrosch <frosch@openttd.org>2015-04-23 20:07:07 +0000
commit8ffe068c118086efd65974ad1fdacaaedd49504f (patch)
tree40b4549176867eefd6925c3eeafc079314a5db88
parent9de0eccf7f9cae0836670865d0aae87768f30fbd (diff)
downloadopenttd-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.cpp41
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();
}