* @brief Creates a new String object initialized with the given initial string. * * This function allocates memory for a new String object and initializes it with the provided initial string. * If the initial string is not provided (i.e., NULL), the String object will be created with an empty string. * The function also initializes a memory pool for efficient memory management of the string d
| 368 | * @return A pointer to the newly created String object, or exits the program with an error if memory allocation fails. |
| 369 | */ |
| 370 | String* string_create(const char* initialStr) { |
| 371 | STRING_LOG("[string_create]: Creating string with initial content: %s", initialStr ? initialStr : "(null)"); |
| 372 | |
| 373 | String* str = (String*)malloc(sizeof(String)); |
| 374 | if (!str) { |
| 375 | STRING_LOG("Error: Memory allocation failed for String object in string_create."); |
| 376 | return NULL; |
| 377 | } |
| 378 | |
| 379 | size_t initialSize = initialStr ? strlen(initialStr) : 0; |
| 380 | str->size = initialSize; |
| 381 | str->capacitySize = 32 + initialSize; // +1 for null terminator |
| 382 | |
| 383 | STRING_LOG("[string_create]: Initial size: %zu, Capacity size: %zu", initialSize, str->capacitySize); |
| 384 | |
| 385 | |
| 386 | /* Size the per-string bump pool to this string's actual needs (with a |
| 387 | * little headroom so a few in-place growths stay contiguous), NOT a fixed |
| 388 | * 1 MB. A fixed huge pool made N strings cost N MB (e.g. 100000 strings -> |
| 389 | * ~100 GB -> malloc fails -> dataStr NULL -> crash). Anything that outgrows |
| 390 | * this small block transparently spills to tracked heap allocations in |
| 391 | * memory_pool_allocate, so growth still works for large strings. */ |
| 392 | size_t initialPoolSize = (str->capacitySize + 1) * 4; |
| 393 | if (initialPoolSize < 128) { |
| 394 | initialPoolSize = 128; |
| 395 | } |
| 396 | str->pool = memory_pool_create(initialPoolSize); |
| 397 | if (!str->pool) { |
| 398 | STRING_LOG("[string_create]: Error: Memory pool creation failed in string_create."); |
| 399 | free(str); |
| 400 | return NULL; |
| 401 | } |
| 402 | |
| 403 | str->dataStr = (char*) memory_pool_allocate(str->pool, str->capacitySize); |
| 404 | if (!str->dataStr) { |
| 405 | STRING_LOG("[string_create]: Error: Memory pool allocation failed in string_create."); |
| 406 | memory_pool_destroy(str->pool); |
| 407 | free(str); |
| 408 | return NULL; |
| 409 | } |
| 410 | |
| 411 | if (initialStr) { |
| 412 | strcpy(str->dataStr, initialStr); |
| 413 | STRING_LOG("[string_create]: String initialized with content: %s", str->dataStr); |
| 414 | } |
| 415 | else { |
| 416 | str->dataStr[0] = '\0'; |
| 417 | } |
| 418 | |
| 419 | registry_add(str); /* track for safe (idempotent) deallocation */ |
| 420 | STRING_LOG("[string_create]: String creation successful."); |
| 421 | return str; |
| 422 | } |
| 423 | |
| 424 | |
| 425 | /** |
no test coverage detected