Как определяется, какой блок памяти использовать в c/c++?

Это код, который я написал:

#include <iostream>
using namespace std;

int main() {
    int x[3] = {30,31,32}, y[3] = {40,41,42}, z[3] = {50,51,52};

    for (int i=0; i < 3; i++) {
        cout << *(x+i) << endl;
        cout << *(x-(3-i)) << endl;
        cout << *(x-(6-i)) << endl;
    }
    cout << endl;
    for (int i=0; i < 3; i++) { 
        cout << (long int)&x[i] << endl; // address of x
    }
    cout << endl;
    for (int i=0; i < 3; i++) {
        cout << (long int)&y[i] << endl; // address of y
    }
    cout << endl;
    for (int i=0; i < 3; i++) {
        cout << (long int)&z[i] << endl; // address of z
    }
}

Вот результат:

30
40
50
31
41
51
32
42
52

140701886846268
140701886846272
140701886846276

140701886846256
140701886846260
140701886846264

140701886846244
140701886846248
140701886846252

Здесь вы можете видеть, что массив, который был объявлен последним, занимает первый адрес памяти, а предпоследний занимает адрес памяти после последнего и так далее.

Это зависит от компилятора. Почему тебе не все равно? Какую реальную проблему вы пытаетесь решить?

kaylum 17.05.2022 07:59

В вашей программе есть неопределенное поведение, потому что вы выходите за границы массива.

Anoop Rana 17.05.2022 08:03

Не думайте, что x[3], y[3] и z[3] связаны вместе. Если вы не объявите их как один массив или std::vector

Louis Go 17.05.2022 08:05

так это не всегда так? может тоже случайно?

Sevam Khadka 17.05.2022 08:07

Я бы не сказал, что это случайно. У каждого компилятора есть (нетривиальная) реализация, которая это определит. Он может меняться в зависимости от компилируемого кода, флагов компилятора, версии компилятора, операционной системы и т. д.

kaylum 17.05.2022 08:08

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

user207421 17.05.2022 08:24

Не каждая переменная оказывается в стеке, и выравнивание может создавать дыры в кадре стека при добавлении переменных в кадр стека. Приличный компилятор поместит более поздние переменные в дыры, оставленные более ранними переменными. Компиляторы также нередко добавляют переменные в обратном порядке.

Goswin von Brederlow 17.05.2022 10:48

Попробуйте запустить код на godbolt.org/z/5oseKbzGs

Goswin von Brederlow 17.05.2022 10:51
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
8
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Here you can see the array which was declared at last takes the foremost memory address and second last takes memory address after the last one and so on.

Нет, это не то, что происходит. Программа имеет неопределенное поведение, потому что вы выходите за границы массива для выражений *(x-(3-i)) и *(x-(6-i)) для разных значений i.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

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

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


1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

Другие вопросы по теме

Похожие вопросы

Я скомпилировал свой код cpp для создания dll-файла в Visual Studio, но не могу найти сгенерированный dll-файл. Есть ли какое-либо имя по умолчанию для dll в vs.
Неправильные значения печати при повторении массива 2d char
Данные в аргументе int* функции не возвращаются вызывающей стороной
Ошибка: доступ члена к неполному типу''; примечание: предварительное объявление ''
Можно ли использовать `#ifdef` внутри макроса?
Ошибка: ожидался неполный идентификатор перед токеном «{» в Linux gcc
Используют ли предварительно скомпилированные заголовки предварительно скомпилированные заголовки, если они включены, или они предназначены только для файлов .cpp?
Введите каламбур в константном / статическом инициализаторе (построение константы с плавающей запятой из битов)
Могу ли я добавить другую функцию, определенную в моем коде, в вектор, такой как массивы, которые включают адрес функции?
Есть ли способ «сбросить» переменные функций?