Skip to content
Snippets Groups Projects
Commit effedbb3 authored by Maxence Naud's avatar Maxence Naud
Browse files

[Bug] Solve memory leak for complex type parameters serialization

Providing a vector as a Parameter for a GenericOperator caused a memory leak.
Solved using malloc instead of pointers to vector's data
parent f6f1c60c
No related branches found
No related tags found
No related merge requests found
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <numeric> #include <numeric>
#include <cstddef>
namespace Aidge { namespace Aidge {
...@@ -45,9 +46,9 @@ public: ...@@ -45,9 +46,9 @@ public:
{ {
assert(m_Params.find(i_ParamName) != m_Params.end()); assert(m_Params.find(i_ParamName) != m_Params.end());
assert(m_Types.find(i_ParamName) != m_Types.end()); assert(m_Types.find(i_ParamName) != m_Types.end());
assert(m_Params.at(i_ParamName) <= m_OffSet); assert(m_Params.at(i_ParamName) <= m_Size);
assert(typeid(T).name() == m_Types.at(i_ParamName)); assert(typeid(T).name() == m_Types.at(i_ParamName));
return *reinterpret_cast<T *>(m_BeginBuffer + m_Params.at(i_ParamName)); return *reinterpret_cast<T *>(m_Buffer + m_Params.at(i_ParamName));
} }
///\brief Add a parameter value, identified by its name ///\brief Add a parameter value, identified by its name
...@@ -59,12 +60,21 @@ public: ...@@ -59,12 +60,21 @@ public:
/// internal buffer in a new location (previous value is still in memory at its previous location) /// internal buffer in a new location (previous value is still in memory at its previous location)
template<class T> void Add(std::string const &i_ParamName, T const &i_Value) template<class T> void Add(std::string const &i_ParamName, T const &i_Value)
{ {
m_Buffer.resize(m_Buffer.size() + (sizeof(T) / sizeof(uint8_t))); const std::size_t addedSize = sizeof(T) / sizeof(std::uint8_t);
m_BeginBuffer = m_Buffer.data(); // Update buffer ptr in case of memory reordering std::uint8_t *tmp = m_Buffer;
*reinterpret_cast<T *>(m_BeginBuffer + m_OffSet) std::uint8_t *m_NewBuffer = static_cast<std::uint8_t *>(std::malloc((m_Size + addedSize)*sizeof(std::uint8_t)));
= i_Value; // Black-magic used to add anytype into the vector
m_Params[i_ParamName] = m_OffSet; // Copy pointer offset for (std::size_t i = 0; i < m_Size; ++i) {
m_OffSet += sizeof(T); // Increment offset m_NewBuffer[i] = m_Buffer[i];
}
free(tmp);
for (std::size_t i = 0; i < addedSize; ++i) {
m_NewBuffer[m_Size+i] = *(reinterpret_cast<const std::uint8_t *>(&i_Value) + i);
}
m_Buffer = m_NewBuffer;
m_Params[i_ParamName] = m_Size; // Copy pointer offset
m_Size += addedSize; // Increment offset
m_Types[i_ParamName] = typeid(i_Value).name(); m_Types[i_ParamName] = typeid(i_Value).name();
} }
...@@ -80,10 +90,14 @@ public: ...@@ -80,10 +90,14 @@ public:
} }
~CParameter() = default; ~CParameter() {
free(m_Buffer);
}
private: private:
// Note for Cyril: of course storing offset and not address! Good idea /// @brief Number of elements in m_Buffer
std::size_t m_Size = 0;
std::map<std::string, std::size_t> m_Params; // { Param name : offset } std::map<std::string, std::size_t> m_Params; // { Param name : offset }
///\brief Map to check type error ///\brief Map to check type error
...@@ -95,16 +109,9 @@ private: ...@@ -95,16 +109,9 @@ private:
std::map<std::string, std::string> m_Types; std::map<std::string, std::string> m_Types;
///\brief All parameters values concatenated in raw binary form. ///\brief All parameters values concatenated in raw binary form.
std::vector<uint8_t> m_Buffer = {}; std::uint8_t *m_Buffer = static_cast<std::uint8_t *>(std::malloc(0));
///\brief Starting address of the buffer
uint8_t *m_BeginBuffer = m_Buffer.data();
///\brief Offset, in number of uint8_t, of the next parameter to write
std::size_t m_OffSet = 0;
}; };
} }
#endif /* __AIDGE_CPARAMETER_H__ */ #endif /* __AIDGE_CPARAMETER_H__ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment