У меня проблема с адресной памятью массива. У меня есть массив 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] имеют одинаковую адресную память. Спасибо.
О, спасибо! Я написал i <= 4 вместо i < 4 в цикле for!
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]? Это случайно?
Массив 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]
Спасибо! Я не знал о распределении памяти в стеке...
Сколько элементов в вашем массиве?
int a[4];
итак 4 элемента. И сколько элементов вы пытаетесь получить доступ?i=0
,i=1
,i=2
,i=3
,i=4
- всего 5 элементов.