#strings.cut memory leak?

1 messages · Page 1 of 1 (latest)

glad umbra
#

Odin is my first foray into manual memory management. I'm using the tracking allocator to help find leaks but I can't seem to figure this this one out. I used strings.cut early in the proc for trimmed_base_path but deleting target_path doesn't have the same result. Any input would be super appreciated.

I did see another related post (https://discord.com/channels/568138951836172421/1183857839538720898) but couldn't work out a solution that worked for my problem.

gen_full_import_path :: proc(base_path: string, import_statement: string) -> string{
    ending_slash_index := strings.last_index(base_path, "/")
    trimmed_base_path := strings.cut(base_path, 0, ending_slash_index + 1)
    defer delete(trimmed_base_path)

    file_name_start_index := strings.index(import_statement, "'")
    file_name_length := strings.last_index(import_statement, "'") - file_name_start_index
    
    target_path := strings.cut(import_statement, file_name_start_index + 1, file_name_length - 1) // <-- The offender
    defer delete(target_path)
    
    if strings.has_prefix(target_path, "./") do target_path = strings.cut(target_path, 2, len(target_path) - 2)
    if strings.contains(target_path, "../") do target_path, _ = strings.replace(target_path, "../", "", 1)
    
    completed_path := strings.concatenate({trimmed_base_path, target_path, ".ts"})
    delete(completed_path)

    return completed_path
}
flat marsh
#

the problem part's the cut & replace below. both of these will make new strings, thus a new allocation, & will replace target_path's assignment.
when you go to delete it. it'll delete only the new strings not the old one.

if strings.has_prefix(target_path, "./") do target_path = strings.cut(target_path, 2, len(target_path) - 2)
if strings.contains(target_path, "../") do target_path, _ = strings.replace(target_path, "../", "", 1)
#

also just return completed_path. doing delete(completed_path) will cause a "use after free" later down the line, as that memory location is now free for other things to use.

flat marsh
#

a way to solve this your issue would be to not make new strings with strings.cut but slice into base_path & import_statement and use the bool from strings.replace to see if you need to deallocate target_path.

rigid sleet
#

Those cuts can probably just be cut_string := original_string[n:]
cut_string has the same lifetime as original_string when you do this; there is no copy.

#

I would also use filepath.join instead of concatenate.
I also would consider doing something like this instead of the replace:

if strings.contains("../") do return "", .Prohibited_Import_Path
glad umbra
#

Thank you both for the feedback. I was able to solve the memory leaks using your suggestions.

glad umbra
simple crown