Как сегменты памяти организованы с точки зрения программы

0

Во-первых, я даю два фрагмента кода функции C/C++, которые показывают разные стратегии, которые C/C++ управляют распределением памяти. Мне задавали эти вопросы на собеседовании. :(

# 1

char *func()
{
    char *p = "hello world";
    return p;
}

# 2

char *func()
{
    char p[] = "hello world";
    return p;
}

Могут ли люди по-прежнему получать строку "hello world", когда функция func возвращается?
Этот ответ - ДА и НЕТ соответственно.
Потому что в # 1 "мир привет" является строковой константой. А в №2 местом хранения "привет мир" является STACK. Но при написании таким образом static char p[] = "hello world"; , ответ будет ДА.

Итак, мой вопрос заключается в том, что как C/C++ управляет распределением памяти функции?
Вспомни, что сказал мне мой интервьюер. Я могу вспомнить что-то вроде: STACK/HEAP/DATA SEGMENT/SEGRMENT ПРОГРАММЫ *. Я хочу, чтобы кто-нибудь мог точно это описать.
Благодарю.


СОДЕРЖАНИЕ ДОБАВЛЕНО

"Знание того, как ваши коды управляются в памяти, поможет программистам написать их код". Это то, что сказал мне интервьюер.
Приведенные выше примеры используются для описания этого. Я хочу спросить, что как сегменты памяти организованы с точки зрения программы. Ответы, которые, как я ожидаю, могут

|___________________|  
|        STACK      |
|___________________|  
|        HEAP       |
|___________________|  
|   DATA SEGMENT    |
|___________________|  
|  PROGRAM SEGMENT  |
|___________________|  
|        ...        |  
|                   |  

С точки зрения программы, я не уверен, что такой раздел памяти правильный. (А также могут существовать другие сегменты, которые хранят данные определенного типа.)

  • 0
    Stack Overflow - это не школа информатики.
  • 0
    Технически, ответ «да» и «возможно». Второй пример - неопределенное поведение.
Показать ещё 1 комментарий
Теги:
function
memory

2 ответа

1

Первый из них в порядке, возвращаемый указатель указывает на постоянный литерал (однако изменение его неопределенного поведения и его должно быть const).

Второй может вызвать неопределенное поведение, он возвращает указатель на локальную переменную, которая будет разрушена после выхода из функции.

Примечание. Константные литералы будут храниться в DATA-SEGMENT (в большинстве реализаций), а не в стеке функций.

  • 0
    Я был разочарован, обнаружив, что gcc -Wall не gcc -Wall предупреждение для char *p = "hello world"; :-(
  • 0
    Я думаю, это потому, что этот фрагмент кода действителен в C (исторически!)
1

Как написано, ваш вопрос слишком широк для полного обращения, поэтому я постараюсь обратиться к конкретным его частям.

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

char *p = "hello world";
return p;

Во втором примере мы создаем массив char[] в стеке и заполняем его, создавая копию строкового литерала. Всякий раз, когда мы объявляем нестатический массив в C, память всегда выделяется в стеке. Поскольку память стека эффективно исчезает, когда функция возвращается, указатель недействителен на возврате функции.

char p[] = "hello world";
return p;

В третьем и последнем примере мы объявляем статический массив. Внутри функции ключевое слово static означает, что переменная имеет продолжительность жизни, равную времени жизни всей программы. Вот почему возвращение указателя на такой массив вполне допустимо, хотя это копия, как и второй пример.

static char p[] = "hello world";

Если вам интересны такие знания, я бы рекомендовал эту слайд-колоду для дальнейшего изучения. Это очень практично и обсуждает эти вопросы в контексте интервью.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню