баг? .
Участников: 5
FreeBasic :: Программирование :: Общее
Страница 1 из 1
баг? .
народ, я тупой, или бага?
- Код:
type tt
s as string
end type
dim as tt ptr t=allocate(sizeof(tt))
print len(t->s)
Re: баг? .
Это багофича. В структурах лучше использовать строки с фиксированной длиной (zstring*X) или zstring ptr. А то получается, что в структуре дескриптор строки, который никак не инициализируется allocate'ом, соответсвенно в нём указатели указывают в null, отсюда и segfault при присваивании.
ExMortis- Сообщения : 11
Дата регистрации : 2009-01-01
Возраст : 41
Откуда : Российская Империя, уездный город Белгород
Re: баг? .
Угу, просто путает тип string, который какбы существует в перемешку со стандартными типами, но в отличие от них является чемто, наподобе класса (похоже тут сказывается какраз те куски ООП-а, реализованные во FB).
Просто в большинстве реализаций бейсика вообще запрещено использовать тип string внутри структур.
С Эриком обсудили эту тему, по его словам здесь необходимо еще использовать нечто, подобное конструктору для типа string, и чтобы явно не заморачиваться с этим, какраз был сделан оператор new, который все подобные операции делает самостоятельно, те код по уму должен выглядеть примерно так
Просто в большинстве реализаций бейсика вообще запрещено использовать тип string внутри структур.
С Эриком обсудили эту тему, по его словам здесь необходимо еще использовать нечто, подобное конструктору для типа string, и чтобы явно не заморачиваться с этим, какраз был сделан оператор new, который все подобные операции делает самостоятельно, те код по уму должен выглядеть примерно так
- Код:
type tt
s as string
end type
dim as tt ptr t=new tt
print len(t->s)
Re: баг? .
привет. да, мы с эриком вроде тоже обсуждали тему allocate и new, и вроде, пришли к мнению, что лучше использовать new.
точнее говоря не мы, а кто-то из сишных программистов это писал.
покрайней мере, выделить 2048 байт можно и allocate, а большие буферы, лучше new.
может я неправ. эрик в си от меня далеко ушёл, поэтому он лучше скажет.
по мне, лучше в стеке зафигачить буфер и все.
хотя считается, что всякие буферы, переменные, связанные со стеком, чреваты плохими последствиями, если стек не восстановлен.
под windows, есть winapi функции, которые создают буферы, потом другими функциями фиксируешь буферы в памяти, но это для быстрых операций, чтоб в файл подкачки не откачался.
я считаю, если вы пишете не многоплатформенную программу, используйте специальные функции os, так программа будет лучше заточена под любимую os.
точнее говоря не мы, а кто-то из сишных программистов это писал.
покрайней мере, выделить 2048 байт можно и allocate, а большие буферы, лучше new.
может я неправ. эрик в си от меня далеко ушёл, поэтому он лучше скажет.
по мне, лучше в стеке зафигачить буфер и все.
хотя считается, что всякие буферы, переменные, связанные со стеком, чреваты плохими последствиями, если стек не восстановлен.
под windows, есть winapi функции, которые создают буферы, потом другими функциями фиксируешь буферы в памяти, но это для быстрых операций, чтоб в файл подкачки не откачался.
я считаю, если вы пишете не многоплатформенную программу, используйте специальные функции os, так программа будет лучше заточена под любимую os.
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Re: баг? .
и снова я чета натворил...
- Код:
dim as string pTmp, pStr
pTmp="><aa"
pStr="qwe" & pTmp & "dsa"
print instr(pStr, pTmp)
print instrrev(pStr, pTmp)
Извините за запоздалый визит...
Чего-то я не пойму. Код тот же, но работает :
- Код:
Type st
As String s
End Type
Dim t As st Ptr=Allocate(SizeOf(st))
Print SizeOf(t->s)
Sleep
t->s=!"Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!Hello!\tHello!\tHello!\tHello!\tHello!\tHello!"
Print t->s
sleep
End
VerhoLom- Сообщения : 67
Дата регистрации : 2010-07-06
Возраст : 42
Re: баг? .
да несовсем тот же, len и sizeof в данном случае применяются к строке, соотвественно работают абсолютно поразному (изначально len какраз только для строк и применялся, это в fb решили сделать алиас с него на sizeof для отличных от string типов)
Re: баг? .
Да, создатели ФБ немного перемутили со строками. Пока не покопаешься в отладчике, толком не разберешся. На самом же деле, все логично. Итак.
В ФБ есть два типа строк - первый, так называемые zstring - это простая последовательность байт, на низком уровне для компилера это все равно что массив символов, с завершаюшим нулем на конце, означающим конец строки. Этот тип хранения строк древний, и отказаться от него совсем нельзя, так как он крайне удобный в некоторых случаях, к тому же самый компактный. Все стандартные функи бацика работают с таким типом строк... но, как оказывается, только перед этим преобразовав его в стандартный string ( о котором поговорим чуть позже). Поэтому, как ни странно, в плане быстродействия лучше использовать не zstring, а string.
Но родным для фб будет тип string, который на самом деле является структурой ( я как-то уже говорил это здесь )
type
as integer len;
as integer size;
as zstring ptr data;
end type
( за точность не ручаюсь, на самом деле выглядит это немного по-другому, но принцип ясен ).
То есть здесь содержится длина строки ( не нужно каждый раз сканить строку ), размер выделенной памяти ( он может отличаться от длины строки ), и указатель на обыкновенную zstring строку! То есть это обертка вокруг древнего zstring.
Так вот. теперь все более-менее ясно, я думаю. если len вычисляет длину строки, то sizeof - не псевдоним, а функция компилятора (кстати, не выдуманная в фб - аналоги есть во многих языках, в том числе и С) вычисляющая размер памяти, занимаемой типом данных, причем всегда в байтах. ( то есть для zstring это будет длина строки + 1 (то есть завершающий ноль) , и умножить на два, если строка unicode utf-16 - то есть каждый символ занимает два байта , а для string - размер вышеописанной структуры, который всегда будет равен 12 байт ).
А вот allocate просто псевдоним для с-шной функции malloc, которая просто выделяет указанный размер памяти (естественно, с помошью тех же стандартных функций WinAPI - не вижу смысла переходить исключительно на них ), и знать не может ни о каких наших типах, и потому даже не инициализирует их нулями (в общем случае). New же воплощен в библиотеке бацика, и потому корректно инициализирует все наши переменные в дефолтные значения.
В ФБ есть два типа строк - первый, так называемые zstring - это простая последовательность байт, на низком уровне для компилера это все равно что массив символов, с завершаюшим нулем на конце, означающим конец строки. Этот тип хранения строк древний, и отказаться от него совсем нельзя, так как он крайне удобный в некоторых случаях, к тому же самый компактный. Все стандартные функи бацика работают с таким типом строк... но, как оказывается, только перед этим преобразовав его в стандартный string ( о котором поговорим чуть позже). Поэтому, как ни странно, в плане быстродействия лучше использовать не zstring, а string.
Но родным для фб будет тип string, который на самом деле является структурой ( я как-то уже говорил это здесь )
type
as integer len;
as integer size;
as zstring ptr data;
end type
( за точность не ручаюсь, на самом деле выглядит это немного по-другому, но принцип ясен ).
То есть здесь содержится длина строки ( не нужно каждый раз сканить строку ), размер выделенной памяти ( он может отличаться от длины строки ), и указатель на обыкновенную zstring строку! То есть это обертка вокруг древнего zstring.
Так вот. теперь все более-менее ясно, я думаю. если len вычисляет длину строки, то sizeof - не псевдоним, а функция компилятора (кстати, не выдуманная в фб - аналоги есть во многих языках, в том числе и С) вычисляющая размер памяти, занимаемой типом данных, причем всегда в байтах. ( то есть для zstring это будет длина строки + 1 (то есть завершающий ноль) , и умножить на два, если строка unicode utf-16 - то есть каждый символ занимает два байта , а для string - размер вышеописанной структуры, который всегда будет равен 12 байт ).
А вот allocate просто псевдоним для с-шной функции malloc, которая просто выделяет указанный размер памяти (естественно, с помошью тех же стандартных функций WinAPI - не вижу смысла переходить исключительно на них ), и знать не может ни о каких наших типах, и потому даже не инициализирует их нулями (в общем случае). New же воплощен в библиотеке бацика, и потому корректно инициализирует все наши переменные в дефолтные значения.
DiG. GeRR- Сообщения : 101
Дата регистрации : 2009-01-30
Возраст : 32
Откуда : Рудный, Казахстан
FreeBasic :: Программирование :: Общее
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
|
|