Система и компилятор:
Эту проблему можно решить с помощью компилятора GNUC или Visual Studio, а также Windows или Linux.
По некоторым особым причинам я реализую собственный класс данных (похожий на std::string), но теперь возникла проблема с освобождением памяти при жизненный цикл объекта.
Позвольте мне сначала объяснить мое требование:
- По особым причинам я не хочу использовать любые интеллектуальные указатели в C++, а вместо этого использовать механизм управления памятью в C.
- Пользователи не могут напрямую манипулировать внутренними элементами данных.
- Не используйте добавьте в этот класс дополнительные функции для освобождения памяти вручную.
Buffer.hpp
#include
#include
#include
#include
class Buffer {
private:
uint8_t *data;
// When writing data in the current space that has been applied for, use.
// This member is used to append written data after this->data.
uint8_t *data_offset;
size_t data_len; // Represents the actual memory length occupied by the data
size_t data_size; // Represents the requested length of memory space
public:
// Hide other constructors and member functions that do not affect the current problem.
Buffer()
: data(nullptr), data_offset(nullptr), data_len(), data_size()
{
}
Buffer(const uint8_t *content, size_t length)
: data(nullptr), data_offset(nullptr), data_len(length), data_size(length)
{
this->data = (uint8_t *)malloc(this->data_len);
if (!this->data) {
throw std::runtime_error("Buffer::Buffer: Failed to allocate memory for this->data.");
}
memcpy(this->data, content, length);
this->data_offset = this->data + length;
}
Buffer(size_t memory_size)
: data(nullptr), data_offset(nullptr), data_len(), data_size(memory_size)
{
this->data = (uint8_t *)malloc(this->data_size);
if (!this->data) {
throw std::runtime_error("Buffer::Buffer: Failed to allocate memory for this->data.");
}
memset(this->data, 0x00, this->data_size);
this->data_offset = this->data;
}
~Buffer()
{
free(this->data);
this->data = nullptr;
}
uint8_t *wuk::Buffer::append_write(size_t length)
{
if(this->is_memory_sufficient(length)) {
this->expand_memory(length);
}
this->data_len += length;
this->data_offset += length;
return this->data_offset - length;
}
// attribute
uint8_t *get_data()
{
return this->data;
}
const char *get_cStr()
{
return reinterpret_cast(this->data);
}
size_t get_length()
{
return this->data_len;
}
size_t get_size()
{
return this->data_size;
}
};
Вот пример использования:
main.cpp
// Assuming the C++ header mentioned earlier is already included.
#include
Buffer get_sha256_digest(Buffer data)
{
Buffer digestBuffer{32};
const EVP_MD *md = EVP_sha256();
EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(md_ctx, md, nullptr);
EVP_DigestUpdate(md_ctx, data.get_data(), data.get_length());
EVP_DigestFinal_ex(md_ctx, digestBuffer.append_write(32), nullptr);
EVP_MD_CTX_free(md_ctx);
return digestBuffer;
}
void new_ctx(const char *password)
{
uint8_t keyWithIV[32+16]{};
Buffer salt_buffer;
salt_buffer = get_sha256_digest({reinterpret_cast(password), strlen(password)});
uint8_t *salt_data = salt_buffer.get_data();
wSize salt_size = salt_buffer.get_length();
PKCS5_PBKDF2_HMAC(password, strlen(password), salt_data, salt_size,
10240, EVP_sha256(), sizeof(keyWithIV), keyWithIV);
}
int main()
{
new_ctx("hello, world.\n");
}
Ошибка компилятора g++ следующая:
sn@Debian:~# g++ main.cpp -O3 -Wall -lz -lssl -lcrypto -o main
In file included from test\main.cc:16:
In destructor 'wuk::Buffer::~Buffer()',
inlined from 'void Crypto_Cipher_FEA::new_ctx(const char*)' at test\main.cc
wuk/sources/WukBuffer.cc:93:9: warning: pointer may be used after 'void free(void*)' [-Wuse-after-free]
93 | free(this->data);
| ~~~~^~~~~~~~~~~~
In destructor 'wuk::Buffer::~Buffer()',
inlined from 'void Crypto_Cipher_FEA::new_ctx(const char*)' at test\main.cc:91:40:
wuk/sources/WukBuffer.cc:93:9: note: call to 'void free(void*)' here
93 | free(this->data);
| ~~~~^~~~~~~~~~~~
test\main.cc: In member function 'void Crypto_Cipher_FEA::new_ctx(const char*)':
test\main.cc:96:26: warning: pointer may be used after 'void free(void*)' [-Wuse-after-free]
96 | PKCS5_PBKDF2_HMAC(password, strlen(password), salt_data, salt_size,
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97 | 10240, EVP_sha256(), sizeof(content), content);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In destructor 'wuk::Buffer::~Buffer()',
inlined from 'void Crypto_Cipher_FEA::new_ctx(const char*)' at test\main.cc:91:40:
wuk/sources/WukBuffer.cc:93:9: note: call to 'void free(void*)' here
93 | free(this->data);
| ~~~~^~~~~~~~~~~~
Подробнее здесь: https://stackoverflow.com/questions/791 ... ailed-in-c