Just starting out? Need help? Post your questions and find answers here.
StarBootics
Addict
Posts: 984 Joined: Sun Jul 07, 2013 11:35 am
Location: Canada
Post
by StarBootics » Mon Nov 18, 2019 7:03 pm
Hello everyone,
I have question here, with the given code snippet how to free memory without causing a memory leak
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Question
; File Name : How to Free Memory.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 18-11-2019
; Last Update : 18-11-2019
; PureBasic code : V5.71 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Memory = AllocateMemory(3*SizeOf(String))
*Ptr.String = Memory
*Ptr\s = "PureBasic"
*Ptr + SizeOf(String)
*Ptr\s = "Version 5.71 LTS x64"
*Ptr + SizeOf(String)
*Ptr\s = "November 18th, 2019"
FreeMemory(Memory)
Debug *Ptr\s
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
mk-soft
Always Here
Posts: 5393 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Mon Nov 18, 2019 7:32 pm
Code: Select all
; Bugfix PB v5.7x
CompilerIf #PB_Compiler_Version < 570
Macro Nothing
#Null$
EndMacro
CompilerElse
Macro Nothing
"!_PB_NullConstant_!"
EndMacro
CompilerEndIf
Memory = AllocateMemory(3*SizeOf(String))
*Ptr.String = Memory
*Ptr\s = "PureBasic"
*Ptr + SizeOf(String)
*Ptr\s = "Version 5.71 LTS x64"
*Ptr + SizeOf(String)
*Ptr\s = "November 18th, 2019"
*Ptr = Memory
*Ptr\s = Nothing
*Ptr + SizeOf(String)
*Ptr\s = Nothing
*Ptr + SizeOf(String)
*Ptr\s = Nothing
FreeMemory(Memory)
Debug *Ptr\s
Better over structure
Code: Select all
Structure udtString
s1.s
s2.s
s3.s
EndStructure
*mem.udtString = AllocateStructure(udtString)
*mem\s1 = "PureBasic"
*mem\s2 = "Version 5.71 LTS x64"
*mem\s3 = "November 18th, 2019"
FreeStructure(*mem)
Debug *mem\s3 ; <- No memory leak. Old Data
I like this...
Code: Select all
Procedure FreeMemoryPtr(*Memory.integer)
If *Memory
FreeMemory(*Memory\i)
*Memory\i = 0
EndIf
EndProcedure
Procedure FreeStructurePtr(*Memory.integer)
If *Memory
FreeStructure(*Memory\i)
*Memory\i = 0
EndIf
EndProcedure
Structure udtString
s1.s
s2.s
s3.s
EndStructure
*mem.udtString = AllocateStructure(udtString)
*mem\s1 = "PureBasic"
*mem\s2 = "Version 5.71 LTS x64"
*mem\s3 = "November 18th, 2019"
Debug *mem\s1 + #LF$ + *mem\s2 + #LF$ + *mem\s3
FreeStructurePtr(@*mem)
If *mem
Debug *mem\s3
Else
Debug "No Memory"
EndIf
Last edited by
mk-soft on Mon Nov 18, 2019 7:45 pm, edited 1 time in total.
StarBootics
Addict
Posts: 984 Joined: Sun Jul 07, 2013 11:35 am
Location: Canada
Post
by StarBootics » Mon Nov 18, 2019 7:43 pm
Thanks for the quick response.
But I can't use a structure since I don't know in advance how many string I will have.
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
IdeasVacuum
Always Here
Posts: 6425 Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:
Post
by IdeasVacuum » Mon Nov 18, 2019 7:44 pm
Hi StarBootics
- can't allocate memory as SizeOf(String), it's ambiguous?
Code: Select all
sMyString.s = "PureBasic" + #CRLF$ + "Version 5.71 LTS x64" + #CRLF$ + "November 18th, 2019"
*MyMem = AllocateMemory(StringByteLength(sMyString, #PB_UTF8) + 1)
PokeS(*MyMem, sMyString, -1, #PB_UTF8)
Debug PeekS(*MyMem, -1, #PB_UTF8)
FreeMemory(*MyMem)
Edited: Allocate Memory: Add a byte for string end Null (0). Thanks mk-soft
Last edited by
IdeasVacuum on Mon Nov 18, 2019 9:45 pm, edited 1 time in total.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
mk-soft
Always Here
Posts: 5393 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Mon Nov 18, 2019 7:49 pm
Hi IdeasVacuum,
You forget Nullbyte...
Code: Select all
*MyMem = AllocateMemory(StringByteLength(sMyString, #PB_UTF8) + 1) ; + SizeOf(Character) for ASCII and Unicode
mk-soft
Always Here
Posts: 5393 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Mon Nov 18, 2019 7:57 pm
Example 1
Code: Select all
;-TOP
; For PB Function
Procedure MyString(Array Result.s(1))
Protected cnt, i
cnt = Random(10, 1)
Dim Result(cnt)
For i = 0 To cnt
Result(i) = "Text " + Str(i)
Next
ProcedureReturn cnt
EndProcedure
Dim text.s(0)
Define c = MyString(text())
For i = 0 To c
Debug text(i)
Next
Josh
Addict
Posts: 1183 Joined: Sat Feb 13, 2010 3:45 pm
Post
by Josh » Mon Nov 18, 2019 7:58 pm
StarBootics wrote: But I can't use a structure since I don't know in advance how many string I will have.
The use of an unstructured memory block is the worst solution to store pointers. If you want to store an unknown number of pointers, use a linked list consisting of pointers.
sorry for my bad english
mk-soft
Always Here
Posts: 5393 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Mon Nov 18, 2019 8:38 pm
Example 2
Bugfix - forget free buffer
Code: Select all
;-TOP
; For DLL like API
Procedure Unicode(Text.s)
Protected *mem = AllocateMemory(StringByteLength(Text) + SizeOf(Unicode))
If *mem
PokeS(*mem, Text, -1, #PB_Unicode)
EndIf
ProcedureReturn *mem
EndProcedure
; ----
Global NewMap CheckStringBuffer.i()
ProcedureDLL MyStringResult(*Buffer.integer)
Protected *mem.integer, cnt
If *Buffer = 0
ProcedureReturn -1 ; Invalid Pointer
EndIf
cnt = Random(10, 1)
*mem = AllocateMemory((cnt + 2) * SizeOf(integer))
If *mem
AddMapElement(CheckStringBuffer(), Str(*mem))
CheckStringBuffer() = cnt
*Buffer\i = *mem
For i = 0 To cnt
*mem\i = Unicode("Text " + Str(i))
*mem + SizeOf(integer)
Next
ProcedureReturn cnt + 1
Else
ProcedureReturn -2 ; Out Of Memory
EndIf
EndProcedure
ProcedureDLL MyFreeString(*Buffer)
Protected *mem.integer = *Buffer
If *Buffer
If FindMapElement(CheckStringBuffer(), Str(*Buffer))
*mem = *Buffer
While *mem\i
FreeMemory(*mem\i)
*mem\i = 0
*mem + SizeOf(integer)
Wend
FreeMemory(*Buffer)
DeleteMapElement(CheckStringBuffer())
EndIf
EndIf
EndProcedure
; ----
Define *Buffer
Define cnt
cnt = MyStringResult(@*Buffer)
Debug "Count: " + cnt
If cnt > 0
*string = *Buffer
For i = 1 To cnt
Debug PeekS(PeekI(*string))
*string + SizeOf(integer)
Next
EndIf
MyFreeString(*Buffer)
Last edited by
mk-soft on Mon Nov 18, 2019 9:46 pm, edited 1 time in total.
IdeasVacuum
Always Here
Posts: 6425 Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:
Post
by IdeasVacuum » Mon Nov 18, 2019 9:33 pm
Hi mk-soft ... The null byte is automatically added by PB - you have to use a flag to omit it if required.
Edit: Ah no, you mean the allocation - yes, should be 1 byte added for Null.
Last edited by
IdeasVacuum on Mon Nov 18, 2019 9:43 pm, edited 1 time in total.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
mk-soft
Always Here
Posts: 5393 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Mon Nov 18, 2019 9:42 pm
Sorry, but your memory is to short...
StringByteLen give the length of string without null byte.
Code: Select all
len = StringByteLength("0123456789")
Debug Len
PokeS write with null byte over your memory size...
Ok , you have see. Sorry
IdeasVacuum
Always Here
Posts: 6425 Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:
Post
by IdeasVacuum » Wed Nov 20, 2019 4:26 pm
Hi StarBootics
I don't know in advance how many string I will have
Why not simply use a List (linked List)? It's a powerful, fast and easy way to manage an unknown number of strings.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Josh
Addict
Posts: 1183 Joined: Sat Feb 13, 2010 3:45 pm
Post
by Josh » Wed Nov 20, 2019 4:40 pm
IdeasVacuum wrote: Why not simply use a List (linked List)? It's a powerful, fast and easy way to manage an unknown number of strings.
This or a list of pointers, as I have described above. Unfortunately it is not possible to see what StarBootics actually intends.
sorry for my bad english
StarBootics
Addict
Posts: 984 Joined: Sun Jul 07, 2013 11:35 am
Location: Canada
Post
by StarBootics » Wed Nov 20, 2019 5:44 pm
Josh wrote: IdeasVacuum wrote: Why not simply use a List (linked List)? It's a powerful, fast and easy way to manage an unknown number of strings.
This or a list of pointers, as I have described above. Unfortunately it is not possible to see what StarBootics actually intends.
It's very simple, I want to create a data structure that I manage my self like I did with my
ByteVector but for string instead of byte.
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
Josh
Addict
Posts: 1183 Joined: Sat Feb 13, 2010 3:45 pm
Post
by Josh » Wed Nov 20, 2019 10:06 pm
StarBootics wrote: It's very simple, I want to create a data structure that I manage my self like I did with my
ByteVector but for string instead of byte.
With the
code you linked , I tried to change it to lists. So your question from here shouldn't be an issue anymore.
sorry for my bad english
StarBootics
Addict
Posts: 984 Joined: Sun Jul 07, 2013 11:35 am
Location: Canada
Post
by StarBootics » Wed Nov 20, 2019 10:53 pm
Josh wrote: StarBootics wrote: It's very simple, I want to create a data structure that I manage my self like I did with my
ByteVector but for string instead of byte.
With the
code you linked , I tried to change it to lists. So your question from here shouldn't be an issue anymore.
If I wanted to use a linked list to store the data I would have done it that way, it's clear. And it's exactly what I don't want to do.
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !