С++: у меня есть два массива, в которых первый и последний элементы имеют одинаковый адрес памяти

У меня проблема с адресной памятью массива. У меня есть массив A[4] и массив B[4]. Я заметил, что когда я печатаю &A[0] и &B[4], эти два имеют одинаковую адресную память. Я не знаю, почему и как это исправить. Это мой код на С++

#include < iostream>


int main()
{

    int a[4];
    int b[4];




for (int i=0; i<=4; i++)
{

    std::cout << &a[i] << std::endl;
    std::cout << &b[i] << std::endl;
    std::cout << "___________" << std::endl;
    a[i] = i;
    b[i] =i;
}

printf("a:b\n");
for (int i=0; i<=4; i++)
    printf("%d:%d\n", a[i], b[i]);

}

Вот что печатает:

0x61fe00

0x61fdf0


0x61fe04

0x61fdf4


0x61fe08

0x61fdf8


0x61fe0c

0x61fdfc


0x61fe10

0x61fe00


а:б

4:0

1:1

2:2

3:3

4:4

Я не знаю, почему a[0] и b[4] имеют одинаковую адресную память. Спасибо.

Сколько элементов в вашем массиве? int a[4]; итак 4 элемента. И сколько элементов вы пытаетесь получить доступ? i=0, i=1, i=2, i=3, i=4 - всего 5 элементов.

Yksisarvinen 14.12.2020 10:51

О, спасибо! Я написал i <= 4 вместо i < 4 в цикле for!

Emmanuelle 14.12.2020 10:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
183
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

b[4] ​​находится за пределами памяти, назначенной для b, поэтому вполне может быть, что b[4] ссылается на начало a, a[0]. B начинается в b[0] и заканчивается в b[3].

Ваш цикл неверен - он зацикливается на пяти элементах, а ваши массивы имеют только четыре элемента. Поскольку b следует за a в стеке, адрес после последнего элемента a фактически является первым элементом b.

Короче говоря, в массивах нет ничего плохого, вам просто нужно правильно зациклиться, изменив условие <= на <:

for (int i=0; i<4; i++)
{
    // Here ---^
    std::cout << &a[i] << std::endl;
    std::cout << &b[i] << std::endl;
    std::cout << "___________" << std::endl;
    a[i] = i;
    b[i] =i;
}

b[4] не является элементом b, это одно прошедшее, а затем конец b. Вы можете получить указатель на него, так что &b[4] в порядке, но использование его в противном случае является неопределенным поведением, поэтому присваивание b[i] = i с i на 4 означает, что все может случиться

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

Я не знаю, почему и как это исправить.

Не пытайтесь получить доступ за пределы массива. Индекс 4 находится за пределами последнего действительного индекса.

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

Это связано с тем, что a, b являются локальными переменными и помещаются в стек последовательно, т.е. b помещается после a. Поэтому, когда вы печатаете адрес b[4] (сразу за границей массива b, поскольку b[3] является последним элементом b), он фактически указывает на адрес начала массива a, то есть a[0].

Хорошо, спасибо, теперь я понимаю свою ошибку: b[4] не выходит. Но я до сих пор не понимаю, почему b[4] указывает на адресную память [0]? Это случайно?

Emmanuelle 14.12.2020 11:07

Массив a помещается в стек, а затем массив b. поэтому внутренние адреса стека будут выглядеть как b[0],b[1],b[2],b[3],a[0],a[1],a[2],a[3]. Итак, когда вы печатаете b[4] (означает сдвиг 4 элементов от b[0]), это адрес a[0]

gobinda 14.12.2020 11:12

Спасибо! Я не знал о распределении памяти в стеке...

Emmanuelle 14.12.2020 11:17

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