Автор | Сообщение |
|
| постоянный участник
|
Пост N: 2010
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 14:50. Заголовок: Local переменные и время ее жизни....
Столкнулся с непонятками у себя в коде... хХарбор 1.2 Вот "вырезка" из моей функции. Function MyFun LOCAL aPoleField := {}, aPoleField2 := {} ? LEN(aPoleField), LEN(aPoleField2) wait aPoleField := GetProfile( cSection, "Массив полей" , { } ) // Функция считывания массива с ИНИ-файла aPoleField2 := GetProfile( cSection, "Массив полей2" , { } ) // Функция считывания массива с ИНИ-файла ? LEN(aPoleField), LEN(aPoleField2) IF LEN(aPoleField2) > 0 FOR nI := 1 TO LEN(aPoleField2) AADD( aPoleField , aPoleField2[nI] ) NEXT ENDIF ?? " -> ",LEN(aPoleField), LEN(aPoleField2) wait aPoleField := {} aPoleField2 := {} ? LEN(aPoleField), LEN(aPoleField2) wait RETYRN NIL При 1-ом вызове дает правильное значение, допустим: 0, 0 6, 4, -> 10, 4 0, 0 При 2-ом вызове дает уже неправильное значение 0, 0 10, 4, -> 14, 4 0, 0 При 3-ом вызове дает уже: 0, 0 14, 4, -> 18, 4 0, 0 и т.д. Что за ерунда получается ? Ведь если LOCAL переменная - то она же нулевая при входе. А у меня получается что нет ! Колонки в таблице при каждом входе "размножаются" как кролики (добавляются по 4 штуки)... Как такое может быть ???
|
|
|
Ответов - 20
[только новые]
|
|
|
| |
Пост N: 2265
Зарегистрирован: 17.05.05
|
|
Отправлено: 19.01.12 14:56. Заголовок: Andrey Вроде все ве..
Andrey Вроде все верно ;) При входе LOCAL aPoleField := {}, aPoleField2 := {} Cоответственно получаем ? LEN(aPoleField), LEN(aPoleField2) // 0,0
|
|
|
|
| |
Пост N: 116
Зарегистрирован: 11.10.11
|
|
Отправлено: 19.01.12 14:57. Заголовок: Надо смотреть не это..
Надо смотреть не этот код, а код функции GetProfile( cSection, "Массив полей" , { } ). Ведь у вас в приведенном коде имеет место присвоение массива. Поэтому эти локальные переменные содержат то, что им было присвоено после вызова функции.
|
|
|
|
| постоянный участник
|
Пост N: 2011
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 14:59. Заголовок: Dima пишет: Andrey ..
Dima пишет: цитата: | Andrey Вроде все верно ;) |
| А дальше ерунда получается .... Как функция может вернуть в 1разе правильное значение, а дальше по нарастанию ? Т.е. сколько раз зашли, на столько и добавили !!!
|
|
|
|
| |
Пост N: 2266
Зарегистрирован: 17.05.05
|
|
Отправлено: 19.01.12 15:02. Заголовок: Andrey пишет: А дал..
Andrey пишет: цитата: | А дальше ерунда получается |
| Сыроежка пишет: цитата: | Надо смотреть не этот код, а код функции GetProfile( cSection, "Массив полей" , { } ). |
| +1
|
|
|
|
| постоянный участник
|
Пост N: 2012
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 15:04. Заголовок: Сыроежка пишет: Над..
Сыроежка пишет: цитата: | Надо смотреть не этот код, а код функции GetProfile( cSection, "Массив полей" , { } ) |
| Если убрать IF LEN(aPoleField2) > 0 FOR nI := 1 TO LEN(aPoleField2) AADD( aPoleField , aPoleField2[nI] ) NEXT ENDIF То всегда будет правильно ! Как этот кусок кода (добавление массива) влияет на функцию GetProfile( cSection, "Массив полей" , { } ) ? Ведь переменная aPoleField здесь, только в этой функции, а "Массив полей" в другой функции, там другая переменная !!!
|
|
|
|
| |
Пост N: 2267
Зарегистрирован: 17.05.05
|
|
Отправлено: 19.01.12 15:09. Заголовок: Andrey пишет: Как э..
Andrey пишет: цитата: | Как этот кусок кода (добавление массива) влияет на функцию GetProfile( cSection, "Массив полей" , { } ) ? |
| Ни как не влияет и похоже ты заблудился в трёх соснах ;)
|
|
|
|
| постоянный участник
|
Пост N: 2013
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 15:10. Заголовок: Dima пишет: Ни как ..
Dima пишет: цитата: | Ни как не влияет и похоже ты заблудился в трёх соснах ;) |
| Да может и заблудился. Я код конечно могу и переписать, но хочется понять с этой проблемой, где я туплю.
|
|
|
|
| |
Пост N: 117
Зарегистрирован: 11.10.11
|
|
Отправлено: 19.01.12 15:11. Заголовок: Andrey пишет: Если ..
Andrey пишет: цитата: | Если убрать IF LEN(aPoleField2) > 0 FOR nI := 1 TO LEN(aPoleField2) AADD( aPoleField , aPoleField2[nI] ) NEXT ENDIF То всегда будет правильно ! Как этот кусок кода (добавление массива) влияет на функцию GetProfile( cSection, "Массив полей" , { } ) ? |
| Все равно надо смотреть код функции GetProfile( cSection, "Массив полей" , { } ), и в как она возвращает значение. Может быть функция возвращает ссылку на массив. То есть в любом случае анализировать представленный вами код бессмысленно. Он ничего не скажет.
|
|
|
|
| |
Пост N: 2268
Зарегистрирован: 17.05.05
|
|
Отправлено: 19.01.12 15:12. Заголовок: Сыроежка пишет: Все..
Сыроежка пишет: цитата: | Все равно надо смотреть код функции GetProfile( cSection, "Массив полей" , { } ), |
| +1
|
|
|
|
| постоянный участник
|
Пост N: 2014
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 15:22. Заголовок: Вот эта функция. ..
Вот эта функция. Скрытый текст // Определения для структуры INI массива #define INI_SECTION 1 #define INI_KEY 2 #define INI_VALUE 3 #define INI_TEXT 4 STATIC aConfig FUNCTION GetProfile( cSection, cKey, xDefault ) // Отыскивается значение cKey в разделе cSection INI массива. // Если не найдено ключевое выражение, то возвращается значение xDefault. LOCAL nPos, xRetVal cSection := ALLTRIM( UPPER( cSection ) ) cKey := ALLTRIM( UPPER( cKey ) ) IF ( nPos := ASCAN( aConfig, ; { | a | ALLTRIM( UPPER( a[ INI_SECTION ] ) ) == cSection .AND. ; ALLTRIM( UPPER( a[ INI_KEY ] ) ) == cKey ; } ; ) ) > 0 xRetVal := aConfig[ nPos, INI_VALUE ] ELSE xRetVal := xDefault ENDIF RETURN ( xRetVal )
|
|
|
|
|
| |
Пост N: 118
Зарегистрирован: 11.10.11
|
|
Отправлено: 19.01.12 15:31. Заголовок: Надо смотреть код, п..
Надо смотреть код, помимо приведенного, где происходит обращение к статическому массиву aConfig. Вставьте перед выходом из функции отладочную печать размера этого массива и посмотрите, как она будет меняться.
|
|
|
|
|
| постоянный участник
|
Пост N: 698
Зарегистрирован: 27.01.07
|
|
Отправлено: 19.01.12 15:48. Заголовок: Andrey, где заполняе..
Andrey, где заполняется массив aConfig?
|
|
|
|
| постоянный участник
|
Пост N: 2015
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 15:50. Заголовок: Поставил. Получается..
Поставил. Получается что при 1-ом считывании: aPoleField := GetProfile( cSection, "Массив полей" , { } ) // Функция считывания массива с ИНИ-файла aPoleField2 := GetProfile( cSection, "Массив полей2" , { } ) // Функция считывания массива с ИНИ-файла Возвращает 6 и 4 значений. Добавляем массив: IF LEN(aPoleField2) > 0 FOR nI := 1 TO LEN(aPoleField2) AADD( aPoleField , aPoleField2[nI] ) NEXT ENDIF Делаем сразу: aPoleField := GetProfile( cSection, "Массив полей" , { } ) // Функция считывания массива с ИНИ-файла Уже 10 значений ! Как такое происходит ? В этой же функции GetProfile() нет никаких присвоений и добавлений в массив?
|
|
|
|
| постоянный участник
|
Пост N: 2016
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 15:54. Заголовок: PSP пишет: Andrey,..
PSP пишет: цитата: | Andrey, где заполняется массив aConfig? |
| В начале запуска задачи. Считывается ИНИ-файл программы. Туда к этому массиву имеет доступ только спец.функции, которыми я не пользуюсь. Получается что добавление LOCAL переменных добавляет в STATIC-массив. Голова кругом уже идет, 3-ий день долблюсь...
|
|
|
|
| |
Пост N: 119
Зарегистрирован: 11.10.11
|
|
Отправлено: 19.01.12 15:58. Заголовок: Давно я не работал с..
Давно я не работал с Clipper! Но очевидно происходит слледующее. при возврате значения передается handle, указывающий на подмассив aСonfig. И когда вы выполняете копирование, на самом деле вы копируете в исходный массив. То есть при возврате значения никакого нового массива не создается, а создается локальная ссылка на массив. Эта локальная ссылка на исходный массив присваивается вашей локальной переменной. И ваша локальная переменная указаывает на тот же самый массив.
|
|
|
|
| постоянный участник
|
Пост N: 699
Зарегистрирован: 27.01.07
|
|
Отправлено: 19.01.12 16:01. Заголовок: Конечно, ссылка. Нуж..
Конечно, ссылка. Нужно AClone() использовать.
|
|
|
|
| постоянный участник
|
Пост N: 2017
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 16:04. Заголовок: PSP пишет: Конечно..
PSP пишет: цитата: | Конечно, ссылка. Нужно AClone() использовать. |
| Расшифруй....
|
|
|
|
| постоянный участник
|
Пост N: 700
Зарегистрирован: 27.01.07
|
|
Отправлено: 19.01.12 16:10. Заголовок: Попробуй в функции G..
Попробуй в функции GetProfile() вместо xRetVal := aConfig[ nPos, INI_VALUE ] использовать xRetVal := AClone( aConfig[ nPos, INI_VALUE ] ).
|
|
|
|
| |
Пост N: 120
Зарегистрирован: 11.10.11
|
|
Отправлено: 19.01.12 16:12. Заголовок: Clipper не передает ..
Clipper не передает массивы, так как сами массивы могут занимать много памяти. Например, в Clipper размер массива может достигать 64Kb. Поэтому через свой стек Clipper передает указатель на виртуальный сегмент, где хранится массив. То есть в Clipper представление всех данных занимает 14 байтов. Этот размер одинаков, что для числовых данных, что для логических данных, что для строк, что для указателей на массив. Для указателей на массив он хранит указатель на виртуальный сегмент, где расположен массив. Этот указатель и возвращается из вашей функции в вызывающую функцию. И по-прежнему указывает на тот же самый виртуальный сегмент, где расположен массив. Локальным является лишь сам указатель на массив.
|
|
|
|
| постоянный участник
|
Пост N: 2018
Зарегистрирован: 12.09.06
|
|
Отправлено: 19.01.12 16:21. Заголовок: Понял. Буду теперь з..
Понял. Буду теперь знать. Спасибо БОЛЬШОЕ за разъяснения !
|
|
|
|