почему возвращаемое значение функции может быть назначено? - PullRequest
1 голос
/ 02 августа 2011

Рассмотрим следующую функцию:

 char *f()
 {   
 char *s=malloc(8);
 }
 main()
 {
  printf("%c",*f()='A');
 }

Если я прокомментирую строку char *s=malloc(8);, я получаю сообщение об ошибке, как будто присвоение *f()='A' получило доступ к недействительной памяти. Поскольку я никогда не возвращаю переменную, почему вышеупомянутое назначение вообще работает?

2-й вопрос: 'A' присваивается временной переменной, созданной при возврате функции. Так почему же ++a и т. Д. Нельзя использовать в качестве lvalue?

Ответы [ 6 ]

4 голосов
/ 02 августа 2011

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

При назначении на *f() вы назначаете не временное, а память, возвращенную из malloc.Назначение ++ a совершенно другое.

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

1 / Возвращение f () является неинициализированным указателем, но существует.
* f () возвращает значение, указанное по неопределенному (случайному) адресу.
Запись по этому адресу является недопустимым доступом к памятиили, возможно, нет, если этот адрес «случайно» является записываемым фрагментом памяти (стеком или ранее выделенной кучей).
В C вы несете ответственность за обеспечение правильного доступа к памяти.

2 / «А» здесь не назначено временному.

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

В вашей функции вы возвращаете указатель, где вы можете назначить вещи ... ++a предотвращает это, возвращая const ссылку или экземпляр. вы можете иметь такое же поведение, если у вас есть const char* f() { ... }.

Конечно, вы также можете реализовать ++a по-другому:)

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

Ваша функция ничего не возвращает.Поскольку вы объявляете функцию с типом возврата char *, ничего не возвращая приводит к неопределенному поведению, как определено в пункте 6.6.3.2 текущего стандарта C ++:

вытекает из концафункция эквивалентна return без значения;это приводит к неопределенному поведению в функции, возвращающей значение.

Неопределенное поведение означает, что может случиться что угодно .Чтобы решить эту проблему, ваша функция должна выглядеть следующим образом:

char *f()
{   
    return malloc(8);
}
0 голосов
/ 02 августа 2011

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

char *f()
{   
    char *s=malloc(8);
    return s;
}
0 голосов
/ 02 августа 2011

Ваша функция f() ничего не возвращает, вам нужно добавить:

return s;

Но, честно говоря, это только начало ваших проблем.Вам также нужно free() вернуть значение f().

Я не знаю, почему вы отметили этот вопрос C ++, это явно C, и поэтому я не пометил как таковой.

...