У меня была та же проблема, и я решил ее при помощи кода 'сервлета по умолчанию' от кодовой базы Tomcat.
http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
DefaultServlet является сервлетом, который служит статическим ресурсам (jpg, HTML, css, gif и т.д.) в Tomcat.
Этот сервлет очень эффективен и имеет некоторых свойства, которые Вы определили выше.
я думаю, что этот исходный код, хороший способ запустить и удалить функциональность или depedencies, в котором Вы не нуждаетесь.
Это не вызовет утечки памяти. Это вызовет висящую ссылку. Локальная переменная размещается в стеке и будет освобождена, как только выйдет за пределы области видимости. В результате, когда функция завершается, возвращаемый вами указатель больше не указывает на память, которой вы владеете. Это не утечка памяти (утечка памяти - это когда вы выделяете часть памяти и не освобождаете ее).
[Обновление] : Чтобы иметь возможность вернуть массив, выделенный в функции, вы должны выделить его вне стека (например, в куче), например:
char *test() {
char* arr = malloc(100);
arr[0] = 'M';
return arr;
}
Теперь, если вы не освободите
память в вызывающей функции после вы закончили его использовать, произойдет утечка памяти.
Нет, утечки не будет, так как он будет уничтожен после завершения getp ();
Это приведет к неопределенному поведению, потому что теперь у вас есть указатель на область памяти, которая больше не хранит то, что вы думаете, что это так, и это может быть использовано кем угодно.
Утечка памяти может произойти, если вы сохраните этот массив в куче, не выполняя вызов free ().
char* getp(){
char* p = malloc(N);
//do stuff to p
return p;
}
int main(){
char* p = getp();
//free(p) No leak if this line is uncommented
return 0;
}
Здесь p не уничтожается, потому что его не в стеке, а в куче. Однако после завершения программы выделенная память не высвобождается, что вызывает утечку памяти (даже если это происходит после завершения процесса).
[ОБНОВЛЕНИЕ]
Если вы хотите вернуть новую c-строку из функции, у вас есть два варианта.
, например:
//doesnt exactly answer your update question, but probably a better idea.
size_t foo (const char* str, size_t strleng, char* newstr);
Здесь вам нужно будет где-то выделить память для newstr (может быть стек ИЛИ куча) перед вызовом функции foo. В этом конкретном случае он вернет количество символов в newstr.
Это не утечка памяти, потому что память освобождается правильно.
Но это ошибка. У вас есть указатель на нераспределенную память. Он называется висящей ссылкой и является частым источником ошибок в C. Результаты не определены. Когда вы попытаетесь использовать этот указатель, вы не увидите никаких проблем до выполнения.
Автоматические переменные уничтожаются в конце вызова функции; вы не можете вернуть на них указатель. То, что вы делаете, можно описать как «возвращение указателя на блок памяти, который раньше содержал s, но теперь не используется (но может все еще что-то в нем есть, по крайней мере, сейчас), и он будет быстро заполнен чем-то остальное полностью. "
Это не вызовет утечки памяти, но вызовет неопределенное поведение. Этот случай особенно опасен, потому что указатель будет указывать где-то в стеке программы, и если вы его используете, вы получите доступ к случайным данным. Такой указатель, будучи записанным, также может использоваться для нарушения безопасности программы и выполнения произвольного кода.
s
- это стековая переменная - ссылка на нее автоматически отменяется в конце функции. Однако ваш указатель недействителен и будет относиться к области памяти, которая может быть перезаписана в любой момент.
Никто еще не упомянул другой способ сделать эту конструкцию действительной: сообщить компилятору, что вы хотите, чтобы массив «s» имел «статическую продолжительность хранения» (это означает, что он живет на время жизни программы, как глобальная переменная). Вы делаете это с помощью ключевого слова static:
char *getp()
{
static char s[] = "hello";
return s;
}
Обратной стороной этого является то, что теперь имеется только один экземпляр s, совместно используемый при каждом вызове функции getp (). С функцией, которую вы написали, это не имеет значения. В более сложных случаях он может делать не то, что вы хотите.
PS: Обычный вид локальных переменных имеет так называемую «автоматическую продолжительность хранения», что означает, что новый экземпляр переменной создается, когда функция вызывается и исчезает, когда функция возвращается.
Я удалил свой предыдущий ответ после помещая код в отладчик и наблюдая за дизассемблированием и окном памяти.
Код в вопросе недействителен и возвращает ссылку на стековую память, которая будет перезаписана.
Эта немного другая версия, однако, возвращает ссылка на фиксированную память и отлично работает:
char *getp()
{
char* s = "hello";
return s;
}