Fix memory bugs in shift left.
This commit is contained in:
parent
a8b09001f7
commit
cc17abea53
5
Arena.h
5
Arena.h
|
@ -188,7 +188,12 @@ private:
|
|||
/// Write an Arena out to the output stream.
|
||||
///
|
||||
/// The resulting output looks something like
|
||||
/// ```
|
||||
/// Arena<allocated>@0x7fff91dfad70,store<128B>@0x0055d6c5881ec0.
|
||||
/// ^ ^ ^ ^
|
||||
/// | +- base memory | +- store memory
|
||||
/// +- arena type +- arena size
|
||||
/// ```
|
||||
///
|
||||
/// \param os
|
||||
/// \param arena
|
||||
|
|
24
Buffer.cc
24
Buffer.cc
|
@ -180,8 +180,10 @@ Buffer::Resize(size_t newCapacity)
|
|||
memcpy(newContents, this->contents, this->length);
|
||||
}
|
||||
|
||||
delete this->contents;
|
||||
if (this->length > 0) {
|
||||
delete[] this->contents;
|
||||
this->contents = nullptr;
|
||||
}
|
||||
this->contents = newContents;
|
||||
this->capacity = newCapacity;
|
||||
}
|
||||
|
@ -223,7 +225,7 @@ Buffer::Reclaim()
|
|||
return;
|
||||
}
|
||||
|
||||
delete this->contents;
|
||||
delete[] this->contents;
|
||||
this->contents = nullptr;
|
||||
this->capacity = 0;
|
||||
}
|
||||
|
@ -289,6 +291,7 @@ Buffer::shiftRight(size_t offset, size_t delta)
|
|||
|
||||
if (this->length == 0) return 0;
|
||||
|
||||
|
||||
memmove(this->contents + (offset + delta), this->contents + offset,
|
||||
this->length);
|
||||
return resized;
|
||||
|
@ -298,8 +301,21 @@ Buffer::shiftRight(size_t offset, size_t delta)
|
|||
bool
|
||||
Buffer::shiftLeft(size_t offset, size_t delta)
|
||||
{
|
||||
memmove(this->contents + offset, this->contents + (offset + delta),
|
||||
this->length);
|
||||
if (delta == 0) {
|
||||
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()) {
|
||||
return this->Trim() != 0;
|
||||
|
|
|
@ -4,6 +4,8 @@ project(klib LANGUAGES CXX
|
|||
DESCRIPTION "Kyle's C++ library")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_VERBOSE_MAKEFILES TRUE)
|
||||
set(VERBOSE YES)
|
||||
|
||||
if (MSVC)
|
||||
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")
|
||||
|
|
|
@ -12,19 +12,27 @@ main(int argc, char *argv[])
|
|||
(void) argv;
|
||||
|
||||
Buffer buffer("hlo, world");
|
||||
Buffer helloWorld("hello, world!");
|
||||
Buffer goodbyeWorld("goodbye, world");
|
||||
Buffer goodbyeCruelWorld("goodbye, cruel world");
|
||||
|
||||
std::cout << buffer << std::endl;
|
||||
|
||||
buffer.Insert(1, (uint8_t *) "el", 2);
|
||||
buffer.Append('!');
|
||||
assert(buffer == helloWorld);
|
||||
|
||||
std::cout << buffer << std::endl;
|
||||
|
||||
buffer.Remove(buffer.Length() - 1);
|
||||
std::cout << buffer << std::endl;
|
||||
buffer.Remove(0, 5);
|
||||
std::cout << buffer << std::endl;
|
||||
buffer.Insert(0, 'g');
|
||||
std::cout << buffer << std::endl;
|
||||
buffer.Insert(1, (uint8_t *) "oodbye", 6);
|
||||
std::cout << buffer << std::endl;
|
||||
assert(buffer == goodbyeWorld);
|
||||
buffer.Insert(9, (uint8_t *)"cruel ", 6);
|
||||
|
||||
std::cout << buffer << std::endl;
|
||||
|
|
BIN
dictionary_test
BIN
dictionary_test
Binary file not shown.
35
klib.h
35
klib.h
|
@ -20,20 +20,39 @@
|
|||
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
/// 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
|
||||
#define KLIB_KLIB_H
|
||||
|
||||
|
||||
/// 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
|
||||
|
|
Loading…
Reference in New Issue