LINUX.ORG.RU

Корректно возвращено значение?


0

0

Что-то я не понимаю, корректно ли будет работать следующий код:

static const char *showbits(int count)

{

if (count > 32) return "*too many bits*";

return 0;

}

Не будет память, занятая под массив char, помещена как свободная после выхода из функции showbits?


Да, все совершенно корректно. Со строка такое проходит нормально. Это исключение из общего правила.

devinull ★★
()
Ответ на: комментарий от Tsahes

> Спасибо, не знал. Почитаю про исключения.

только не забывайте это исключение обрабатывать

// wbr

klalafuda ★☆☆
()

Не нашел ни в Страуструпе, ни в гугле упоминания об особенности возврата строки функцией.

Встретил в Intermediate C Programming Class Notes упоминание о невозможности возврата массива из функции:

"Since it's a regular local variable, it has automatic duration, which means that it springs into existence when the function is called and disappears when the function returns. Therefore, the pointer that this <skip> returns is to an array which no longer exists by the time the caller receives the pointer. Functions must never return pointers to local, automatic-duration arrays."

Если не трудно, поделитесь источником информации.

Tsahes
() автор топика
Ответ на: комментарий от Tsahes

Язык программирования C++. коприрайт сам знаешь чей. Параграф 5.2.2 Строковые литералы.

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

const char* error_message( int i )
{
  // ...
  return "выход за пределы диапазона";
}

Память, содержащая строку "выход за пределы диапазона", не будет освобождена после вызова функции error_message();

PS: ну, вот тебе и разница между C-строкой и простым массивом =)

devinull ★★
()
Ответ на: комментарий от devinull

Поучительные примеры:

#include <stdio.h>

char *str(void)
{
int a=1,b=2,c=3;
   printf("str:%p %p %p \n",&a,&b,&c);
   return "The string";
}

int *ptr(void)
{
int a=1;
   printf("ptr:%p\n",&a);
   return (int[]){-1,-2};
}

int main(void)
{
int *p=ptr();
char *s=str();
   printf("pstr=%p str=%s p1=%p p2=%p int1=%d int2=%d\n",s,s,p,p+1,p[0],p[1]);
   return 0;
}

Компилим, запускаем, и видим, что строка "The string" разместилась отнюдь 
не в стеке, и ничего ей не сделается, а вот константный массив в функции 
ptr() оказался в стеке и был затерт при вызове str().

Теперь делаем похожие вызовы, но вместо строки возвращаем ук-ль на 
константный массив:

#include <stdio.h>

char *str(void)
{
int a=1,b=2,c=3;
   printf("str:%p %p %p \n",&a,&b,&c);
   return (char[]){'T','h','e',' ','s','t','r','i','n','g','\0'};
}

int *ptr(void)
{
int a=1;
   printf("ptr:%p\n",&a);
   return (int[]){-1,-2};
}

int main(void)
{
int *p=ptr();
char *s=str();
   printf("pstr=%p str=%s p1=%p p2=%p int1=%d int2=%d\n",s,s,p,p+1,p[0],p[1]);
   return 0;
}

Усе, оно в стеке, который затирается принтэфом.

Чтобы убедиться в этом, тупо скопируем результат куда-нибудь
в более надежное место _до_ printf:

#include <stdio.h>

char *str(void)
{
int a=1,b=2,c=3;
   printf("str:%p %p %p \n",&a,&b,&c);
   return (char[]){'T','h','e',' ','s','t','r','i','n','g','\0'};
}

int *ptr(void)
{
int a=1;
   printf("ptr:%p\n",&a);
   return (int[]){-1,-2};
}

char savecpy[32];
char *tmp=savecpy;

int main(void)
{
int *p=ptr();
char *s=str();
   while( (*tmp++=*s++)!='\0');
   printf("pstr=%p str=%s p1=%p p2=%p int1=%d int2=%d\n",savecpy,savecpy,p,p+1,p[0],p[1]);
   return 0;
}

Die-Hard ★★★★★
()
Ответ на: комментарий от Tsahes

> Не нашел ни в Страуструпе, ни в гугле упоминания об особенности возврата строки функцией.

Возвращается не массив, а указатель на него. Должно быть очевидно...

fk0
()
Ответ на: комментарий от fk0

> Возвращается не массив, а указатель на него. Должно быть очевидно..

Обсуждавшаяся тема совершнно не очевидна - возможно, ты просто не совсем разобрался, о чем речь. Я, например, искренне считал, что такое поведение является особенностью реализации (точнее, всех известных мне реализаций ;)), но не стандартизировано, и поэтому явно писал static для строковых констант, которые хотелось вернуть из функций. Так что большое спасибо автору вопроса и отвечавшим на него людям.

anonymous
()
Ответ на: комментарий от anonymous

anonymous (12.10.2005 12:44:59):

> ...поэтому явно писал static для строковых констант,

Надеюсь, ты понимаешь, что static const в твоем примере ( static const char *showbits(int count) ) ни малейшего влияния на способ размещения возвращаемой константы не оказывают?

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>Надеюсь, ты понимаешь, что static const в твоем примере ( static const char *showbits(int count) ) ни малейшего влияния на способ размещения возвращаемой константы не оказывают?

a. Понимаю. Есть еще много вещей никак не связанных друг с другом ;).

б. Пример не мой.

anonymous
()
Ответ на: комментарий от anonymous

anonymous (*) (12.10.2005 14:43:06):

> Пример не мой.

Тады ой :)

Извиняюсь, проглядел anonymous (*) (12.10.2005 12:44:59):

> ... большое спасибо автору вопроса ...

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.