Fix memory bugs in shift left.

This commit is contained in:
Kyle Isom 2023-10-10 04:22:04 -07:00
parent a8b09001f7
commit cc17abea53
7 changed files with 63 additions and 13 deletions

View File

@ -188,7 +188,12 @@ private:
/// Write an Arena out to the output stream. /// Write an Arena out to the output stream.
/// ///
/// The resulting output looks something like /// The resulting output looks something like
/// ```
/// Arena<allocated>@0x7fff91dfad70,store<128B>@0x0055d6c5881ec0. /// Arena<allocated>@0x7fff91dfad70,store<128B>@0x0055d6c5881ec0.
/// ^ ^ ^ ^
/// | +- base memory | +- store memory
/// +- arena type +- arena size
/// ```
/// ///
/// \param os /// \param os
/// \param arena /// \param arena

View File

@ -180,8 +180,10 @@ Buffer::Resize(size_t newCapacity)
memcpy(newContents, this->contents, this->length); memcpy(newContents, this->contents, this->length);
} }
delete this->contents; if (this->length > 0) {
this->contents = nullptr; delete[] this->contents;
this->contents = nullptr;
}
this->contents = newContents; this->contents = newContents;
this->capacity = newCapacity; this->capacity = newCapacity;
} }
@ -223,7 +225,7 @@ Buffer::Reclaim()
return; return;
} }
delete this->contents; delete[] this->contents;
this->contents = nullptr; this->contents = nullptr;
this->capacity = 0; this->capacity = 0;
} }
@ -289,6 +291,7 @@ Buffer::shiftRight(size_t offset, size_t delta)
if (this->length == 0) return 0; if (this->length == 0) return 0;
memmove(this->contents + (offset + delta), this->contents + offset, memmove(this->contents + (offset + delta), this->contents + offset,
this->length); this->length);
return resized; return resized;
@ -298,8 +301,21 @@ Buffer::shiftRight(size_t offset, size_t delta)
bool bool
Buffer::shiftLeft(size_t offset, size_t delta) Buffer::shiftLeft(size_t offset, size_t delta)
{ {
memmove(this->contents + offset, this->contents + (offset + delta), if (delta == 0) {
this->length); return false;
}
if ((offset+delta) > this->length) {
abort();
}
for (auto i = offset; i <= (this->length-delta); i++) {
this->contents[i] = this->contents[i+delta];
}
for (auto i = this->length-delta; i < this->length; i++) {
this->contents[i] = 0;
}
if (this->AutoTrimIsEnabled()) { if (this->AutoTrimIsEnabled()) {
return this->Trim() != 0; return this->Trim() != 0;

View File

@ -4,6 +4,8 @@ project(klib LANGUAGES CXX
DESCRIPTION "Kyle's C++ library") DESCRIPTION "Kyle's C++ library")
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_VERBOSE_MAKEFILES TRUE)
set(VERBOSE YES)
if (MSVC) if (MSVC)
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>") add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")

View File

@ -12,19 +12,27 @@ main(int argc, char *argv[])
(void) argv; (void) argv;
Buffer buffer("hlo, world"); Buffer buffer("hlo, world");
Buffer helloWorld("hello, world!");
Buffer goodbyeWorld("goodbye, world");
Buffer goodbyeCruelWorld("goodbye, cruel world");
std::cout << buffer << std::endl; std::cout << buffer << std::endl;
buffer.Insert(1, (uint8_t *) "el", 2); buffer.Insert(1, (uint8_t *) "el", 2);
buffer.Append('!'); buffer.Append('!');
assert(buffer == helloWorld);
std::cout << buffer << std::endl; std::cout << buffer << std::endl;
buffer.Remove(buffer.Length() - 1); buffer.Remove(buffer.Length() - 1);
std::cout << buffer << std::endl;
buffer.Remove(0, 5); buffer.Remove(0, 5);
std::cout << buffer << std::endl;
buffer.Insert(0, 'g'); buffer.Insert(0, 'g');
std::cout << buffer << std::endl;
buffer.Insert(1, (uint8_t *) "oodbye", 6); buffer.Insert(1, (uint8_t *) "oodbye", 6);
std::cout << buffer << std::endl; std::cout << buffer << std::endl;
assert(buffer == goodbyeWorld);
buffer.Insert(9, (uint8_t *)"cruel ", 6); buffer.Insert(9, (uint8_t *)"cruel ", 6);
std::cout << buffer << std::endl; std::cout << buffer << std::endl;

Binary file not shown.

35
klib.h
View File

@ -20,20 +20,39 @@
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS /// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
/// SOFTWARE. /// SOFTWARE.
/// ///
/// \mainpage klib documentation
/// Hello, world.
///
/// \section Introduction
///
/// This is a collection of data structures and subroutines that I find
/// useful in building things.
#ifndef KLIB_KLIB_H #ifndef KLIB_KLIB_H
#define KLIB_KLIB_H #define KLIB_KLIB_H
/// klib is the top-level namespace containing all the code in this library. /// klib is the top-level namespace containing all the code in this library.
namespace klib {} namespace klib {
/// \mainpage klib documentation
///
/// \section Introduction
///
/// This is a collection of data structures and subroutines that I find
/// useful in building things.
///
/// This library arose from two main use cases.
///
/// \subsection The modem
///
/// On the one hand, I was building a wireless modem for some Z80 computers I
/// have. I needed to be able to store a phonebook of SSIDs and WPA keys, as
/// well as short names to host:port descriptors. I had a limited amount of of
/// persistent NVRAM storage and no SD card or other removeable media, so
/// typical desktop-oriented serialization mechanisms weren't going to really
/// work well. Furthermore, when working with microcontrollers, I prefer not to
/// dynamically allocate memory as much as possible. This led to building out
/// Arena, TLV::Record to store the records, and finally Dictionary to make use
/// of both of them.
///
///
}
#endif // KLIB_KLIB_H #endif // KLIB_KLIB_H

BIN
tlv_test

Binary file not shown.