diff options
| author | 2024-06-12 08:56:49 -0400 | |
|---|---|---|
| committer | 2024-06-12 08:56:49 -0400 | |
| commit | 26afacd565bff3a016b769cb7ee644b3b75b809d (patch) | |
| tree | ef65b2ed0bf6dbb77d91307ee7519a9b4b92b58e /examples/string/uns_string.c | |
| parent | cheney 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.c | 34 |
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) |
