2013-08-09 3 views
-1

Следующая программа будет печатать на экране «Hello \ nWorld \ n» ('\ n' = line down), как предполагалось. Но на самом деле, как я узнал, что-то здесь сделано не так, как должно быть. Строки «hello» и «world» определены внутри функции (и поэтому являются локальными, и их память освобождается в конце области действия - правильно?). На самом деле мы не делаем malloc для них, как мы предполагаем (чтобы сохранить память после области). Поэтому, когда выполняется a(), стек стека памяти не перемещается вверх, а «мир» будет помещен в память в том же месте, где было «привет»? (похоже, этого не происходит, и я не понимаю, почему, и поэтому почему мне обычно нужно делать это malloc, если на самом деле блок памяти сохраняется и не возвращается после области?)Должен ли я malloc возвращать строку внутри функции?

Thanks ,

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
char *a() 
{ 
    char *str1 = "Hello"; 
    return str1; 
} 

char *b() 
{ 
    char *str2 = "World"; 
    return str2; 
} 

int main() 
{ 
    char *main_str1 = a(); 
    char *main_str2 = b(); 
    puts(main_str1); 
    puts(main_str2); 
    return 0; 

} 

редактировать: Так что вы говорите, на самом деле является то, что мой «привет» строка занимает постоянное место в памяти, и даже если он находится внутри функции, я могу читать его из любого места я хочу, если у меня есть его адрес (поэтому он определен как malloc, но вы не можете его освободить) - правильно?

ответ

0

Константные строки не выделяются в стеке. В стеке выделяется только указатель. Указатель возвращался с a() и b() указывает на некоторую литеральную постоянную часть исполняемой памяти. Another question dealing with this topic

0

В этом случае все работает, потому что строковый литерал выделяется в данных памяти, доступных для всего жизненного цикла программы.
Ваш код эквивалентен (производить тот же результат, я имею в виду):

char *a() 
{ 
    return "Hello"; 
} 

Этот код не работает

char* a() 
{ 
    char array[6]; 
    strcpy(array,"Hello"); 
    return array; 
} 

потому что array[] создается на стеке и разрушается, когда функция, возвращающая

0

Строковые литералы (строки, которые определены с помощью "quotes") создаются статически в памяти программы во время компиляции. Когда вы идете char *str1 = "Hello";, вы не создаете новую память во время выполнения, как вы бы с вызовом malloc.

0

C не обязывает компилятор переместить память в стек, как предлагает OP, и поэтому наблюдаемое поведение не прерывается, как ожидалось.

Модели и оптимизация компилятора могут позволить программе, такой как OP с неопределенным поведением (UB), работать, очевидно, без побочных эффектов, таких как повреждение памяти или seg. Другой компилятор может также скомпилировать тот же код с очень разными результатами.

Версии с выделенной памятью следующим образом:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
char *a() { 
    return strdup("Hello"); // combo strlen, malloc and memcpy 
} 

char *b() { 
    return strdup("World"); 
} 

int main() { 
    char *main_str1 = a(); 
    char *main_str2 = b(); 
    puts(main_str1); 
    puts(main_str2); 
    free(main_str1); 
    free(main_str2); 
    return 0; 
} 
Смежные вопросы