-
Notifications
You must be signed in to change notification settings - Fork 161
Fix memory leak in xml_wrapper #4647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
a1cdb8c
f9e07c3
dbc9372
42ceb1b
7564388
f731fb3
f9476c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |||||
| #pragma once | ||||||
|
|
||||||
| #include <cstdint> | ||||||
| #include <memory> | ||||||
| #include <string> | ||||||
|
|
||||||
| namespace Azure { namespace Storage { namespace _internal { | ||||||
|
|
@@ -19,62 +20,54 @@ namespace Azure { namespace Storage { namespace _internal { | |||||
|
|
||||||
| struct XmlNode final | ||||||
| { | ||||||
| explicit XmlNode(XmlNodeType type, std::string name = std::string()) | ||||||
| : Type(type), Name(std::move(name)) | ||||||
| { | ||||||
| } | ||||||
|
|
||||||
| explicit XmlNode(XmlNodeType type, std::string name, std::string value) | ||||||
| : Type(type), Name(std::move(name)), Value(std::move(value)), HasValue(true) | ||||||
| explicit XmlNode( | ||||||
| XmlNodeType type, | ||||||
| std::string name = std::string(), | ||||||
| std::string value = std::string()) | ||||||
| : Type(type), Name(std::move(name)), Value(std::move(value)) | ||||||
| { | ||||||
| } | ||||||
|
|
||||||
| XmlNodeType Type; | ||||||
| std::string Name; | ||||||
| std::string Value; | ||||||
| bool HasValue = false; | ||||||
| }; | ||||||
|
|
||||||
| class XmlReader final { | ||||||
| public: | ||||||
| explicit XmlReader(const char* data, size_t length); | ||||||
| XmlReader(const char* data, size_t length); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Binary data should be
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. XML data is seldom binary. It's usually printable strings. We should use
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it is string data, it should be |
||||||
| XmlReader(const XmlReader& other) = delete; | ||||||
| XmlReader& operator=(const XmlReader& other) = delete; | ||||||
| XmlReader(XmlReader&& other) noexcept { *this = std::move(other); } | ||||||
| XmlReader& operator=(XmlReader&& other) noexcept | ||||||
| { | ||||||
| m_context = other.m_context; | ||||||
| other.m_context = nullptr; | ||||||
| return *this; | ||||||
| } | ||||||
| XmlReader(XmlReader&& other) noexcept; | ||||||
| XmlReader& operator=(XmlReader&& other) noexcept; | ||||||
| ~XmlReader(); | ||||||
|
|
||||||
| XmlNode Read(); | ||||||
|
|
||||||
| private: | ||||||
| void* m_context = nullptr; | ||||||
| struct XmlReaderContext; | ||||||
| std::unique_ptr<XmlReaderContext> m_context; | ||||||
| }; | ||||||
|
|
||||||
| class XmlWriter final { | ||||||
| public: | ||||||
| explicit XmlWriter(); | ||||||
| XmlWriter(); | ||||||
| XmlWriter(const XmlWriter& other) = delete; | ||||||
| XmlWriter& operator=(const XmlWriter& other) = delete; | ||||||
| XmlWriter(XmlWriter&& other) noexcept { *this = std::move(other); } | ||||||
| XmlWriter& operator=(XmlWriter&& other) noexcept | ||||||
| { | ||||||
| m_context = other.m_context; | ||||||
| other.m_context = nullptr; | ||||||
| return *this; | ||||||
| } | ||||||
| XmlWriter(XmlWriter&& other) noexcept; | ||||||
| XmlWriter& operator=(XmlWriter&& other) noexcept; | ||||||
| ~XmlWriter(); | ||||||
|
|
||||||
| void Write(XmlNode node); | ||||||
|
|
||||||
| std::string GetDocument(); | ||||||
|
|
||||||
| private: | ||||||
| void* m_context = nullptr; | ||||||
| struct XmlWriterContext; | ||||||
| std::unique_ptr<XmlWriterContext> m_context; | ||||||
| }; | ||||||
|
|
||||||
| void XmlGlobalInitialize(); | ||||||
| void XmlGlobalDeinitialize(); | ||||||
|
|
||||||
| }}} // namespace Azure::Storage::_internal | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q2:
Why are you using a copy constructor for name and value and then moving them to
Name? Why not passnmeandvalueasconst&and then constructNameandValuefrom the reference?In other words, something like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed it's better to pass arguments as
const&.I'll fix it thanks!
Bear in mind that I'm porting a fix from https://github.com/ClickHouse/azure-sdk-for-cpp and it's not my code :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LarryOsterman About passing by value or reference, if you look at
sdk/storage/azure-storage-common/src/xml_wrapper.cpp, at all of calling sites of this constructor, we pass by right values (e.g.XmlNode(type, std::move(name), std::move(value))).So if the constructor argument is passed by value, the actual string data is first moved from the local variable of calling site, then moved to XmlNode private members, there's no copy here.
If by const reference, we'll need to make two copies.
There are a lot of discussions on stackoverflow regarding this topic, like https://stackoverflow.com/questions/4321305/best-form-for-constructors-pass-by-value-or-reference