возвращающий указатель на alloca - PullRequest
0 голосов
/ 13 августа 2011

Возвращает ли этот код неверную ссылку на переменную, расположенную в стеке?Или что:

void *f(size_t sz) {
    return alloca(sz);
}

Или это особый случай, который обрабатывается реализацией / поддержкой компилятора alloca, например, f(alloca(size), alloca(size)) будет?

Ответы [ 6 ]

5 голосов
/ 13 августа 2011

alloca выделяет место в кадре стека f. Вы не сможете ничего с ним сделать, когда функция вернется (она больше не «зарезервирована»).

Функция alloca () распределяет байты размера пространства в кадре стека звонящего. Это временное пространство автоматически освобождается, когда функция, вызвавшая alloca (), возвращает своему вызывающему .

2 голосов
/ 02 сентября 2011

this:

void *f() {
    char* pc4 = alloca(4);
    ...
}

в точности так:

void *f() {
    char pc4[4];
    ...
}

Ни вы не можете вернуть / использовать pc4 вне функции во втором случае, ни вы не можете сделать то же самое в первом случае.

1 голос
/ 13 августа 2011

Да, код возвращает неверный указатель. alloca вызов не может быть включен в функцию. Если вам нужно обернуть alloca, вы ограничены макропакетами.

0 голосов
/ 02 сентября 2011

Я никогда не использовал alloca сам, но я читал о «встроенной проблеме» здесь: Почему использование alloca () не считается хорошей практикой?

Ответ "Одна из самых запоминающихся ошибок ..." очень интересен.

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

0 голосов
/ 13 августа 2011

Как уже говорили другие, оно будет освобождено, и я не очень понимаю, как вы могли бы изменить поведение.Если вы посмотрите, как alloca компилируется на amd-64:

pushq   %rbp
movq    %rsp, %rbp
subq    $144, %rsp
movq    %rsp, %rax
addq    $15, %rax
shrq    $4, %rax
salq    $4, %rax
leave
ret

Вы видите

1) Alloca на самом деле не является вызовом функции (потому что, как вы сказали, онапришлось бы обрабатывать стек по-разному!)

2) Что бы ни делал alloca с указателем стека, он просто будет забит в конце функции, когда rbp перезаписывает rsp

Так может вы получите поведение, о котором вы спрашиваете (без написания ассемблера)?Это сложный вопрос, и я не знаю, но похоже, что, вероятно, нет.

0 голосов
/ 13 августа 2011

Согласно Linux Справочная страница :

Функция alloca() выделяет место в кадре стека вызывающий и возвращает указатель на выделенный блок. Это временное пробел автоматически освобождается при выполнении функции, из которой alloca() называется возврат.

Это означает, что попытка получить доступ к памяти, возвращенной f(), приведет к неопределенному поведению, так как оно освобождается при возврате f().

...