How to connect the memory blocks ?

Just starting out? Need help? Post your questions and find answers here.
Johanson
User
User
Posts: 40
Joined: Sat Aug 01, 2020 9:53 am

How to connect the memory blocks ?

Post by Johanson »

I'm having trouble joining memory areas: ABC + D = ABCD

; *source : ABC
; *target : D

CopyMemory(*Target, *Source, 1) ; => DBC

How to connect the memory blocks ?
firace
Addict
Addict
Posts: 899
Joined: Wed Nov 09, 2011 8:58 am

Re: How to connect the memory blocks ?

Post by firace »

Something like this?

Code: Select all

a.s = "ABC"
b.s = "D"

CopyMemory(@b, @a + StringByteLength(peekS(@a)), StringByteLength(peekS(@b))) 

ShowMemoryViewer(@a, StringByteLength(peekS(@a)))
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How to connect the memory blocks ?

Post by infratec »

Hi,

this is not possible with CopyMemory, since there is no 'ReAllocation'.
You need an own procedure for this.
Like:

Code: Select all

EnableExplicit


Procedure.i AppendMemory(*source1, *source2)
  
  Protected *target
  
  *target = AllocateMemory(MemorySize(*source1) + MemorySize(*source2), #PB_Memory_NoClear)
  If *target
    CopyMemory(*source1, *target, MemorySize(*source1))
    CopyMemory(*source2, *target + MemorySize(*source1), MemorySize(*source2))
  EndIf
  
  ProcedureReturn *target
  
EndProcedure



Define *source1, *source2, *target

*source1 = Ascii("ABC")
*source2 = Ascii("D")

*target = AppendMemory(*source1, *source2)

ShowMemoryViewer(*target, MemorySize(*target))
This is only a demonstration, not usefull for strings (terminating 0).
You have to adopt this to your needs.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How to connect the memory blocks ?

Post by infratec »

@Firace

Your example results in an IMA (even if it does not generate an alert)

Code: Select all

*source = Ascii("abcdef")
*target = Ascii("1")

Debug MemorySize(*source)

Debug MemorySize(*target)

CopyMemory(*source, *target + MemorySize(*source), MemorySize(*source))

Debug MemorySize(*target)
The *target needs to be large enough.
It will not be increased.
Johanson
User
User
Posts: 40
Joined: Sat Aug 01, 2020 9:53 am

Re: How to connect the memory blocks ?

Post by Johanson »

Rather, I mean inserting a memory block

SourceBlock_1 ( len=10)
SourceBlock_2 ( len=10)
SourceBlock_3 ( len=10)
. . .
SourceBlock_X ( len=10)
TargetBlock ( len=x*10)

TargetBlock=SourceBlock_2+SourceBlock_2+SourceBlock_3+ ... + SourceBlock_X

Is there a difference between strings and memory blocks (is it all the same for pointers)?
firace
Addict
Addict
Posts: 899
Joined: Wed Nov 09, 2011 8:58 am

Re: How to connect the memory blocks ?

Post by firace »

infratec wrote:@Firace

Your example results in an IMA (even if it does not generate an alert)

Code: Select all

*source = Ascii("abcdef")
*target = Ascii("1")

Debug MemorySize(*source)

Debug MemorySize(*target)

CopyMemory(*source, *target + MemorySize(*source), MemorySize(*source))

Debug MemorySize(*target)
The *target needs to be large enough.
It will not be increased.
Ah, good catch! Thanks.
Johanson
User
User
Posts: 40
Joined: Sat Aug 01, 2020 9:53 am

Re: How to connect the memory blocks ?

Post by Johanson »

@infratec

Code: Select all

  . . .
    CopyMemory(*source2, *target + MemorySize(*source1), MemorySize(*source2))
  . . .
Small correction: "-1"
CopyMemory(*source2, *target + MemorySize(*source1) -1 , MemorySize(*source2))
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: How to connect the memory blocks ?

Post by Olli »

-1 ? Bug creator ?

A string contains one or any characters.
A character contains one or any bytes.

A memory block is considered containing bytes and is measured in bytes.

Firace had given a good tip. But he just used an example which does not use rightly this tip !

An other technic :

Code: Select all

;**************************************************************************
Procedure MemConca(*Mem1, *Mem2, Free2.I = 0)

   Define Size1 = MemorySize(*Mem1)
   Define Size2 = MemorySize(*Mem2)
   *Mem1 = ReAllocateMemory(*Mem1, Size1 + Size2)
   CopyMemory(*Mem2, *Mem1 + Size1)
   If Free2
      FreeMemory(*Mem2)
   EndIf
   ProcedureReturn *Mem1

EndProcedure

*A = MemConca(*A, *B, 1)
User avatar
NicTheQuick
Addict
Addict
Posts: 1224
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: How to connect the memory blocks ?

Post by NicTheQuick »

Yes, there is a difference between Strings and pure Memory. Strings usually consists of 2 Bytes per Character and a Null character at the end, so a String with a length of 10 characters consumes at least 22 Bytes in memory. And all operations like concatenating are solved through Purebasic internal string handling. Also because the last character is always a Null character, it is not possible to use null characters anywhere else in the string.

Memory blocks on the other hand can consist of arbitrary byte patterns, have a defined length and for concatenating them you have to write your own routine for this.
Say if you have 10 memory areas and you want to concatenate them, the easiest way would be to make the first one as big as all 10 areas together and then copy areas 2 to 10 in that first reallocated memory area. Then you can free the memory of areas 2 to 10 again.
Here is a simple example:

Code: Select all

#areas = 10
#size = 10

Dim *memory(#areas - 1)

Define i.i

; Create some memory areas
For i = 0 To #areas - 1
	*memory(i) = AllocateMemory(#size)
	FillMemory(*memory(i), #size, ' ', #PB_Ascii)
	PokeS(*memory(i), "area" + i, #size, #PB_Ascii | #PB_String_NoZero)
Next

; Make the first area big enough
*newSpace = ReAllocateMemory(*memory(0), #areas * #size)
If Not *newSpace
	Debug "Reallocation was not possible."
	End
EndIf
*memory(0) = *newSpace

; Concatenate all areas and free the memory
For i = 1 To #areas - 1
	CopyMemory(*memory(i), *memory(0) + i * #size, #size)
	FreeMemory(*memory(i))
	*memory(i) = 0
Next

; Show the result
Debug PeekS(*memory(0), #areas * #size, #PB_Ascii)
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How to connect the memory blocks ?

Post by infratec »

Code: Select all

#BlockLength = 16
#Blocks = 10


*Target = AllocateMemory(#Blocks * #BlockLength)

*Source1 = AllocateMemory(#BlockLength, #PB_Memory_NoClear)
FillMemory(*Source1, MemorySize(*Source1), 1)

*Source2 = AllocateMemory(#BlockLength, #PB_Memory_NoClear)
FillMemory(*Source2, MemorySize(*Source2), 2)

*Source3 = AllocateMemory(#BlockLength, #PB_Memory_NoClear)
FillMemory(*Source3, MemorySize(*Source1), 3)


CopyMemory(*Source1, *Target + (#BlockLength * 3), MemorySize(*Source1))
CopyMemory(*Source1, *Target + (#BlockLength * 5), MemorySize(*Source1))
CopyMemory(*Source2, *Target + (#BlockLength * 7), MemorySize(*Source2))
CopyMemory(*Source3, *Target + (#BlockLength * 1), MemorySize(*Source3))

ShowMemoryViewer(*Target, MemorySize(*Target))
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: How to connect the memory blocks ?

Post by Olli »

NicTheQuick wrote:Yes, there is a difference between Strings and pure Memory. Strings usually consists of 2 Bytes per Character and a Null character at the end, so a String with a length of 10 characters consumes at least 22 Bytes in memory.
In the Unicode format, which tends happily to generalize itself.

But, a recall could be done. Length of a character :

Ascii : 1 byte
Unicode : 2 byte
UTF-8 : 1+2K bytes* (K being integer and >= 0)

Reference

(*) : I edited my error : I wrote initially << 1+3K bytes >> which is false.

Edit again : finally... I solve the litte problem of WTF-8 : the number of bytes per character is 1 + X
Post Reply