Я предполагаю, что вы читали сообщение bbum о блоках и знаете, что ваш код некорректен, поскольку вы не копируете блоки из стека в кучу.
Это говорит:
for (int i=0; i<3; i++) {
b[i]=^{return i;};
}
выполняет следующие действия в каждой итерации:
- Распределяет пространство в стеке для блочной переменной. Скажем, адрес его памяти A ;
- Создает блок в стеке и присваивает его адрес ( A )
b[i]
;
- В конце итерации, поскольку составной оператор / область действия (
{}
) закончился, извлекает все, что было в стеке, и сбрасывает указатель стека.
Стек увеличивается в начале каждой итерации и уменьшается в конце каждой итерации. Это означает, что все блоки создаются в одном и том же адресе памяти, а именно A . Это также означает, что все элементы в массиве b
в конечном итоге указывают на один и тот же блок, а именно последний созданный блок. Вы можете проверить это, запустив следующий код:
for (int i = 0; i < 3; i++) {
printf("%p", (void *)b[i]);
}
который должен вывести что-то вроде:
0x7fff5fbff9e8
0x7fff5fbff9e8
0x7fff5fbff9e8
Все элементы указывают на один и тот же блок, последний из которых создан в адресе памяти A = 0x7fff5fbff9e8.
С другой стороны, когда вы делаете следующее:
b[0]=^{return j;};
j++;
b[1]=^{return j;};
j++;
b[2]=^{return j;};
нет составного оператора, определяющего одинаковую область действия для всех блоков. Это означает, что каждый раз, когда вы создаете блок, его адрес перемещается вниз по стеку, эффективно назначая разные адреса каждому блоку. Поскольку все блоки разные, они правильно фиксируют текущее значение времени выполнения j
.
Если вы напечатаете адрес этих блоков, как описано ранее, вы должны получить вывод, подобный следующему:
0x7fff5fbff9b8
0x7fff5fbff990
0x7fff5fbff968
, показывающий, что каждый блок имеет свой адрес памяти.