aboutsummaryrefslogtreecommitdiffstats
path: root/examples/string/uns_string.c
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2024-06-12 08:56:49 -0400
committerGravatar Peter McGoron 2024-06-12 08:56:49 -0400
commit26afacd565bff3a016b769cb7ee644b3b75b809d (patch)
treeef65b2ed0bf6dbb77d91307ee7519a9b4b92b58e /examples/string/uns_string.c
parentcheney copying collector (diff)
strings: add more tests
cheney_c89: fix memory leak errors
Diffstat (limited to 'examples/string/uns_string.c')
-rw-r--r--examples/string/uns_string.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/examples/string/uns_string.c b/examples/string/uns_string.c
index e510fcf..219df89 100644
--- a/examples/string/uns_string.c
+++ b/examples/string/uns_string.c
@@ -70,27 +70,43 @@ char *uns_string_ptr(struct uns_gc *gc, struct uns_root_list *root)
void uns_string_alloc(struct uns_gc *gc, struct uns_root_list *root, size_t start_len)
{
+ unsigned char *p;
root->p = gc->alloc_record(gc, NUMBER_OF_IND);
- gc->record_set_ptr(root->p, ALLEN_IND, gc->alloc(gc, sizeof(size_t)));
+ /* The following is incorrect:
+ * gc->record_set_ptr(root->p, ALLEN_IND, gc->alloc(gc, sizeof(size_t)));
+ * This is because gc->alloc() can cause a collection, invalidating root->p,
+ * but root->p may have already been put on the stack.
+ */
+
+ p = gc->alloc(gc, sizeof(size_t));
+ gc->record_set_ptr(root->p, ALLEN_IND, p);
set_allen(gc, root, start_len);
- gc->record_set_ptr(root->p, LEN_IND, gc->alloc(gc, sizeof(size_t)));
+ p = gc->alloc(gc, sizeof(size_t));
+ gc->record_set_ptr(root->p, LEN_IND, p);
set_len(gc, root, 0);
- gc->record_set_ptr(root->p, BYTES_IND, gc->alloc(gc, start_len));
+ p = gc->alloc(gc, start_len);
+ gc->record_set_ptr(root->p, BYTES_IND, p);
}
void uns_string_resize(struct uns_gc *gc, struct uns_root_list *root, size_t newlen)
{
- char *tmp;
+ struct uns_root_list tmp_new = {0};
+ size_t old_len = uns_string_len(gc, root);
+
+ uns_root_add(gc, &tmp_new);
+ uns_string_alloc(gc, &tmp_new, newlen);
- tmp = gc->alloc(gc, newlen);
- set_allen(gc, root, newlen);
+ if (newlen <= old_len)
+ set_len(gc, &tmp_new, newlen);
+ else
+ set_len(gc, &tmp_new, old_len);
- if (newlen <= uns_string_len(gc, root))
- set_len(gc, root, newlen);
- memcpy(tmp, uns_string_ptr(gc, root), uns_string_len(gc, root));
+ memcpy(uns_string_ptr(gc, &tmp_new), uns_string_ptr(gc, root), uns_string_len(gc, root));
+ root->p = tmp_new.p;
+ uns_root_remove(gc, &tmp_new);
}
void uns_string_ensure(struct uns_gc *gc, struct uns_root_list *root, size_t extent)