@@ -83,16 +83,23 @@ static TrieNode* trie_node_add_child(TrieNode* node, int codepoint) {
8383 if (node -> num_children >= node -> capacity ) {
8484 int new_capacity = node -> capacity == 0 ? INITIAL_CAPACITY : node -> capacity * 2 ;
8585
86+ /* Allocate both arrays before updating pointers */
8687 TrieNode * * new_children = (TrieNode * * )realloc (node -> children ,
8788 new_capacity * sizeof (TrieNode * ));
8889 if (!new_children ) return NULL ;
8990
9091 int * new_chars = (int * )realloc (node -> child_chars , new_capacity * sizeof (int ));
9192 if (!new_chars ) {
92- /* Restore old pointer to avoid leak, but still fail */
93+ /* new_children was allocated but new_chars failed */
94+ /* Since realloc succeeded for new_children, the old pointer is invalid */
95+ /* We must use the new_children pointer, even though we can't proceed */
96+ node -> children = new_children ;
97+ /* Alternatively, we could try to restore by reallocating to old size */
98+ /* But that could also fail, so we just update and return NULL */
9399 return NULL ;
94100 }
95101
102+ /* Both allocations succeeded, update pointers */
96103 node -> children = new_children ;
97104 node -> child_chars = new_chars ;
98105 node -> capacity = new_capacity ;
@@ -201,8 +208,11 @@ int trie_prefixes(Trie* trie, const char* text, char*** prefixes, int** lengths)
201208 * prefixes = (char * * )malloc (max_prefixes * sizeof (char * ));
202209 * lengths = (int * )malloc (max_prefixes * sizeof (int ));
203210 if (!* prefixes || !* lengths ) {
204- free (* prefixes );
205- free (* lengths );
211+ /* Clean up any successful allocation */
212+ if (* prefixes ) free (* prefixes );
213+ if (* lengths ) free (* lengths );
214+ * prefixes = NULL ;
215+ * lengths = NULL ;
206216 return 0 ;
207217 }
208218
0 commit comments