diff --git a/ctl/string.cc b/ctl/string.cc index ff864c306..2a2b22eb1 100644 --- a/ctl/string.cc +++ b/ctl/string.cc @@ -99,7 +99,8 @@ string::reserve(size_t c2) noexcept if (!isbig()) { if (!(p2 = (char*)malloc(c2))) __builtin_trap(); - memcpy(p2, data(), size() + 1); + memcpy(p2, data(), size()); + p2[size()] = 0; } else { if (!(p2 = (char*)realloc(big()->p, c2))) __builtin_trap(); @@ -134,18 +135,18 @@ string::append(char ch) noexcept if (ckd_add(&n2, size(), 2)) __builtin_trap(); if (n2 > capacity()) { - size_t c2 = capacity() + 2; + size_t c2 = capacity(); if (ckd_add(&c2, c2, c2 >> 1)) __builtin_trap(); reserve(c2); } data()[size()] = ch; - data()[size() + 1] = 0; if (isbig()) { ++big()->n; } else { --small()->rem; } + data()[size()] = 0; } void diff --git a/ctl/string.h b/ctl/string.h index 858b7a224..c830fdf12 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -151,7 +151,7 @@ class string if (isbig() && big()->c <= __::sso_max) __builtin_trap(); #endif - return isbig() ? __::big_mask & big()->c : __::sso_max; + return isbig() ? __::big_mask & big()->c : __::string_size; } iterator begin() noexcept diff --git a/test/ctl/string_test.cc b/test/ctl/string_test.cc index 1a35cfda3..be664b22b 100644 --- a/test/ctl/string_test.cc +++ b/test/ctl/string_test.cc @@ -23,7 +23,7 @@ #include "libc/runtime/runtime.h" #include "libc/str/str.h" -// #include +#include // #define ctl std int @@ -353,6 +353,22 @@ main() return 78; } + if constexpr (!std::is_same_v) { + // tests the small-string optimization on ctl::string + ctl::string s; + char *d = s.data(); + for (int i = 0; i < 23; ++i) { + s.append('a'); + if (s.data() != d) { + return 79 + i; + } + } + s.append('a'); + if (s.data() == d) { + return 103; + } + } + CheckForMemoryLeaks(); return 0; }