mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
Header changes (include/libipc/buffer.h):
- Rename: additional → mem_to_free (better semantic name)
- Add documentation comments explaining the parameter's purpose
- Clarifies that mem_to_free is passed to destructor instead of p
- Use case: when data pointer is offset into a larger allocation
Implementation changes (src/libipc/buffer.cpp):
- Update parameter name in constructor implementation
- No logic changes, just naming improvement
Test changes (test/test_buffer.cpp):
- Fix TEST_F(BufferTest, ConstructorWithMemToFree)
- Previous test caused crash: passed stack variable address to destructor
- New test correctly demonstrates the parameter's purpose:
* Allocate 100-byte block
* Use offset portion (bytes 25-75) as data
* Destructor receives original block pointer for proper cleanup
- Prevents double-free and invalid free errors
Semantic explanation:
buffer(data_ptr, size, destructor, mem_to_free)
On destruction:
destructor(mem_to_free ? mem_to_free : data_ptr, size)
This allows:
char* block = new char[100];
char* data = block + 25;
buffer buf(data, 50, my_free, block); // Frees 'block', not 'data'
71 lines
1.6 KiB
C++
Executable File
71 lines
1.6 KiB
C++
Executable File
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <tuple>
|
|
#include <vector>
|
|
#include <type_traits>
|
|
|
|
#include "libipc/export.h"
|
|
#include "libipc/def.h"
|
|
|
|
namespace ipc {
|
|
|
|
class IPC_EXPORT buffer {
|
|
public:
|
|
using destructor_t = void (*)(void*, std::size_t);
|
|
|
|
buffer();
|
|
|
|
buffer(void* p, std::size_t s, destructor_t d);
|
|
// mem_to_free: pointer to be passed to destructor (if different from p)
|
|
// Use case: when p points into a larger allocated block that needs to be freed
|
|
buffer(void* p, std::size_t s, destructor_t d, void* mem_to_free);
|
|
buffer(void* p, std::size_t s);
|
|
|
|
template <std::size_t N>
|
|
explicit buffer(byte_t (& data)[N])
|
|
: buffer(data, sizeof(data)) {
|
|
}
|
|
explicit buffer(char & c);
|
|
|
|
buffer(buffer&& rhs);
|
|
~buffer();
|
|
|
|
void swap(buffer& rhs);
|
|
buffer& operator=(buffer rhs);
|
|
|
|
bool empty() const noexcept;
|
|
|
|
void * data() noexcept;
|
|
void const * data() const noexcept;
|
|
|
|
template <typename T>
|
|
T get() const { return T(data()); }
|
|
|
|
std::size_t size() const noexcept;
|
|
|
|
std::tuple<void*, std::size_t> to_tuple() {
|
|
return std::make_tuple(data(), size());
|
|
}
|
|
|
|
std::tuple<void const *, std::size_t> to_tuple() const {
|
|
return std::make_tuple(data(), size());
|
|
}
|
|
|
|
std::vector<byte_t> to_vector() const {
|
|
return {
|
|
get<byte_t const *>(),
|
|
get<byte_t const *>() + size()
|
|
};
|
|
}
|
|
|
|
friend IPC_EXPORT bool operator==(buffer const & b1, buffer const & b2);
|
|
friend IPC_EXPORT bool operator!=(buffer const & b1, buffer const & b2);
|
|
|
|
private:
|
|
class buffer_;
|
|
buffer_* p_;
|
|
};
|
|
|
|
} // namespace ipc
|