On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение
постоянный участник




Пост 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 штуки)...
Как такое может быть ???


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 20 [только новые]


администратор




Пост N: 2265
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.01.12 14:56. Заголовок: Andrey Вроде все ве..


Andrey
Вроде все верно ;)
При входе
LOCAL aPoleField := {}, aPoleField2 := {}

Cоответственно получаем
? LEN(aPoleField), LEN(aPoleField2) // 0,0

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 116
Зарегистрирован: 11.10.11
ссылка на сообщение  Отправлено: 19.01.12 14:57. Заголовок: Надо смотреть не это..


Надо смотреть не этот код, а код функции GetProfile( cSection, "Массив полей" , { } ). Ведь у вас в приведенном коде имеет место присвоение массива. Поэтому эти локальные переменные содержат то, что им было присвоено после вызова функции.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2011
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 19.01.12 14:59. Заголовок: Dima пишет: Andrey ..


Dima пишет:

 цитата:
Andrey
Вроде все верно ;)



А дальше ерунда получается .... Как функция может вернуть в 1разе правильное значение, а дальше по нарастанию ?
Т.е. сколько раз зашли, на столько и добавили !!!


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2266
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.01.12 15:02. Заголовок: Andrey пишет: А дал..


Andrey пишет:

 цитата:
А дальше ерунда получается



Сыроежка пишет:

 цитата:
Надо смотреть не этот код, а код функции GetProfile( cSection, "Массив полей" , { } ).



+1

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост 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 здесь, только в этой функции, а "Массив полей" в другой функции, там другая переменная !!!

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2267
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.01.12 15:09. Заголовок: Andrey пишет: Как э..


Andrey пишет:

 цитата:
Как этот кусок кода (добавление массива) влияет на функцию GetProfile( cSection, "Массив полей" , { } ) ?


Ни как не влияет и похоже ты заблудился в трёх соснах ;)

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2013
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 19.01.12 15:10. Заголовок: Dima пишет: Ни как ..


Dima пишет:

 цитата:
Ни как не влияет и похоже ты заблудился в трёх соснах ;)



Да может и заблудился. Я код конечно могу и переписать, но хочется понять с этой проблемой, где я туплю.

Спасибо: 0 
ПрофильЦитата Ответить



Пост 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, "Массив полей" , { } ), и в как она возвращает значение. Может быть функция возвращает ссылку на массив. То есть в любом случае анализировать представленный вами код бессмысленно. Он ничего не скажет.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2268
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.01.12 15:12. Заголовок: Сыроежка пишет: Все..


Сыроежка пишет:

 цитата:
Все равно надо смотреть код функции GetProfile( cSection, "Массив полей" , { } ),


+1

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2014
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 19.01.12 15:22. Заголовок: Вот эта функция. ..


Вот эта функция.

Скрытый текст


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 118
Зарегистрирован: 11.10.11
ссылка на сообщение  Отправлено: 19.01.12 15:31. Заголовок: Надо смотреть код, п..


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

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 698
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 19.01.12 15:48. Заголовок: Andrey, где заполняе..


Andrey, где заполняется массив aConfig?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост 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() нет никаких присвоений и добавлений в массив?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2016
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 19.01.12 15:54. Заголовок: PSP пишет: Andrey,..


PSP пишет:

 цитата:

Andrey, где заполняется массив aConfig?


В начале запуска задачи. Считывается ИНИ-файл программы.
Туда к этому массиву имеет доступ только спец.функции, которыми я не пользуюсь.

Получается что добавление LOCAL переменных добавляет в STATIC-массив.
Голова кругом уже идет, 3-ий день долблюсь...

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 119
Зарегистрирован: 11.10.11
ссылка на сообщение  Отправлено: 19.01.12 15:58. Заголовок: Давно я не работал с..


Давно я не работал с Clipper!
Но очевидно происходит слледующее. при возврате значения передается handle, указывающий на подмассив aСonfig. И когда вы выполняете копирование, на самом деле вы копируете в исходный массив.

То есть при возврате значения никакого нового массива не создается, а создается локальная ссылка на массив. Эта локальная ссылка на исходный массив присваивается вашей локальной переменной. И ваша локальная переменная указаывает на тот же самый массив.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 699
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 19.01.12 16:01. Заголовок: Конечно, ссылка. Нуж..


Конечно, ссылка. Нужно AClone() использовать.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2017
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 19.01.12 16:04. Заголовок: PSP пишет: Конечно..


PSP пишет:

 цитата:

Конечно, ссылка. Нужно AClone() использовать.


Расшифруй....

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 700
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 19.01.12 16:10. Заголовок: Попробуй в функции G..


Попробуй в функции GetProfile()
вместо xRetVal := aConfig[ nPos, INI_VALUE ]
использовать
xRetVal := AClone( aConfig[ nPos, INI_VALUE ] ).

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 120
Зарегистрирован: 11.10.11
ссылка на сообщение  Отправлено: 19.01.12 16:12. Заголовок: Clipper не передает ..


Clipper не передает массивы, так как сами массивы могут занимать много памяти. Например, в Clipper размер массива может достигать 64Kb. Поэтому через свой стек Clipper передает указатель на виртуальный сегмент, где хранится массив. То есть в Clipper представление всех данных занимает 14 байтов. Этот размер одинаков, что для числовых данных, что для логических данных, что для строк, что для указателей на массив. Для указателей на массив он хранит указатель на виртуальный сегмент, где расположен массив.
Этот указатель и возвращается из вашей функции в вызывающую функцию. И по-прежнему указывает на тот же самый виртуальный сегмент, где расположен массив. Локальным является лишь сам указатель на массив.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2018
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 19.01.12 16:21. Заголовок: Понял. Буду теперь з..


Понял. Буду теперь знать.
Спасибо БОЛЬШОЕ за разъяснения !

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 24
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет