Парни, подскажите - где я не догоняю и как надо! Компелю в vc6.0 следующий код: Код (Text): #include <stdio.h> #include <stdlib.h> char *S1() { char *p="TEST_String"; return(p); } char *S2() { char *p=NULL; char a[12]="TEST_String"; p=a; return(p); } /////////// void main() { char *p=NULL; char a[12]="TEST_String"; p=a; printf("Result: %s\n",p); p=S1(); printf("Result: %s\n",p); p=S2(); printf("Result: %s\n",p); } В итоге: Result: TEST_String Result: TEST_String Result: TEST Ффункция S2()???
Строка улыбается . Суть в том, что в первом случае "TEST_String" размещается в секции данных, а во втором -- в стеке, который нельзя использовать после выхода из ф-ии S2. Это все равно что вернуть адрес локальной переменной, которая действительна только в пределах ф-ии, в которой она объявлена. По выходу из этой ф-ии эту переменную использовать нельзя, даже если есть ее адрес.
Функция S1: Строка размещена в сегменте данных, p - указатель на нее. После возврата из функции указатель валидный, данные валидные, всё ок Функция S2: Строка копируется в массив, размещенный на стеке. Возвращается указатель на локальную переменную. С фреймом после возврата может быть все что угодно, данные херятся main: данные копируются в локальную переменную, размещенную в стек-фрейме функции main. До возврата из main они валидные, можно использовать любые указатели на них, все ок. А что именно вы добиться пытаетесь? Локальную строковую переменную завести? Или вернуть строку из функции?
Mika0x65 и Mentor спасибо! Вцелом понятно, за исключением мелочей, которых не хватает для полного восприятия всей картины. Поясните, пожалуйста, один момент: Почему при вызове Функции S1 строка размещается в сегменте данных? По причине явной инициализации?
vb_man Из-за синтаксиса фактически. Т.е. 'char *ptr = "abc";' говорит компилятору: "размести строку в секции данных, а во время выполнения ф-ии положи в ptr ее адрес", а 'char ptr[] = "abc";' -- "размести во время выполнения строку в стеке, а в ptr положи ее адрес". Если взять отладчик, например, Olly, то все это можно увидеть в динамике.
Не совсем верно: ptr, в данном случае, не указатель а сам массив/строка (разница в том, что для char *ptr значения выражений ptr и &ptr различны, а для char ptr[] — нет).
Спасибо за комментарий!. Ни первый год давлю кнопку F7, но указатели по хорошему никак не хотят в моей голове укладываться.
Вчера ночью не догнал о чем Вы! А на самом деле строка действительно издевательски улыбалась моей безграмотности.