Очевидные проблемы:
- не NUL, завершение копирования в
copyStr
- возвращение указателя на локальную переменную в
upper
В C нельзя передавать (в качестве аргументов) или возвращать (в качестве возвращаемого значения) строки «напрямую», поскольку они не являются типами значений - вместо этого вы должны передать или вернуть указатель. Всякий раз, когда вы имеете дело с указателями, вам нужно беспокоиться о времени жизни вещей, на которые указывают, как если бы вы использовали указатель после того, как закончился срок жизни указателя, вы получаете неопределенное поведение.
Итак, чтобы " Чтобы вернуть строку из функции, вы должны фактически вернуть указатель на то, что имеет время жизни, которое продолжается после того, как функция вернулась (что означает, что она не может быть указателем на локальный переменный функции). Как правило, есть три способа устроить это:
- передать указатель на то, куда поместить результирующую строку в качестве дополнительного аргумента (это то, что вы делаете с вашей функцией
copyStr
) - используйте mallo c, чтобы выделить динамическое c пространство для строки и вернуть указатель на нее.
- вернуть указатель на строку c (global).
У каждого из них есть свои недостатки:
- вызывающий должен знать, какой большой размер строки будет возвращен (чтобы создать объект, на который он передал указатель) перед ним даже делает звонок. Часто это невозможно или требует выделения большой строки в «наихудшем случае», или существует опасность переполнения буфера (вызывающего UB). По крайней мере, вам часто требуется второй дополнительный аргумент для указания размера буфера.
- Вызывающая сторона должна «взять на себя ответственность» за возвращенную память и убедиться, что она освобождается должным образом. Это становится частью неявного контракта между вызывающей и вызываемой сторонами, но часто не документируется, поэтому является общим источником утечек памяти
- Все вызовы, как правило, совместно используют один и тот же статус c global, поэтому он не является повторно входящим или потоком -безопасно.