Меня всегда смущает возврат строкового литерала или строки из функции.
Неизменяемая буквенная строка
Насколько я понимаю, вы можете безопасно возвращать строковый литерал напрямую, если тип возвращаемого значения объявлен const, чтобы объявить, что строка не предназначена для изменения. Это означает, что вам не нужно беспокоиться о продолжительности жизни строк/утечек памяти.
Изменяемая нелитеральная строка
Однако, если вам нужна строка, которую можно изменить на месте, необходимо учитывать срок жизни строки и размер выделенной памяти, в которой она хранится. Это становится проблемой, поскольку вы больше не можете беспечно возвращать одну и ту же память, содержащую строку, для каждого вызова функции, поскольку предыдущее использование могло изменить содержимое этой памяти и/или может все еще использоваться. Следовательно, для хранения возвращаемой строки должен быть выделен новый участок памяти.
Именно здесь возникает потенциальная утечка, и здесь необходимо сделать выбор относительно того, где должно происходить выделение и отмена распределения. Вы можете сделать так, чтобы функция сама выделяла память и заявляла в документации, что это происходит, и оговаривала, что вызывающая сторона должна освобождать память, когда она больше не требуется (предотвращая утечку). Это означает, что функция может просто вернуть char *.
Другой вариант — передать некоторую память функции, которая была выделена вызывающей стороной, и заставить функцию поместить строку в эту память. В этом случае вызывающий объект и выделяет, и несет ответственность за освобождение этой памяти.
Наконец, я упомянул, что при использовании изменяемой строки необходимо управлять размером памяти и строки. Выделение должно быть достаточно большим как для строки, первоначально установленной функцией, так и для любых изменений, сделанных после функции, до освобождения памяти. Если вы не сделаете это правильно, это может привести к переполнению буфера из-за того, что строка будет слишком длинной, чтобы поместиться в первоначально выделенную память; это чрезвычайно опасно для здоровья и безопасности вашей программы. Это может привести к ошибкам и дырам в безопасности, которые чрезвычайно трудно обнаружить (поскольку источник ошибки — переполнение — может быть далек от симптомов, наблюдаемых при сбое программы).
person
Mike Tunnicliffe
schedule
20.03.2010
char*
вместоchar const*
, фактически вынуждает нас предположить, что простого строкового литерала недостаточно, и поэтомуreturn "hello world";
является недопустимым решением. Каковы ваши требования к постоянству? - person Johannes Schaub - litb   schedule 20.03.2010