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.
|
/// 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
|
||||||
|
|
24
Buffer.cc
24
Buffer.cc
|
@ -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) {
|
||||||
|
delete[] this->contents;
|
||||||
this->contents = nullptr;
|
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;
|
||||||
|
|
|
@ -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>")
|
||||||
|
|
|
@ -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;
|
||||||
|
|
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
|
/// 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
|
||||||
|
|
Loading…
Reference in New Issue