Question about MID$, and temporary string

General FreeBASIC programming questions.
Post Reply
lassar
Posts: 306
Joined: Jan 17, 2006 1:35

Question about MID$, and temporary string

Post by lassar »

In the following code, does FreeBasic create a temporary string from MID$(LineString$, Start% +1, Length%) before copying it to ReturnLine


Code: Select all

DIM ReturnLine AS ZSTRING * 78

ReturnLine = MID$(MyString$, Start%, Length%)
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Question about MID$, and temporary string

Post by MichaelW »

It looks like 0.23.0 did, but you should probably check the source for the current version.

Code: Select all

/*
 * str_mid.c -- mid$ function
 *
 * chng: oct/2004 written [v1ctor]
 *
 */

#include <stddef.h>
#include <string.h>
#include "fb.h"


/*:::::*/
FBCALL FBSTRING *fb_StrMid ( FBSTRING *src, int start, int len )
{
    FBSTRING 	*dst;
    int			src_len;

	FB_STRLOCK();

    if( (src != NULL) && (src->data != NULL) && (FB_STRSIZE( src ) > 0) )
	{
        src_len = FB_STRSIZE( src );

        if( (start > 0) && (start <= src_len) && (len != 0) )
        {
        	--start;

        	if( len < 0 )
        		len = src_len;

        	if( start + len > src_len )
        		len = src_len - start;

			/* alloc temp string */
            dst = fb_hStrAllocTemp_NoLock( NULL, len );
			if( dst != NULL )
            {
				FB_MEMCPY( dst->data, src->data + start, len );
				/* null term */
				dst->data[len] = '\0';
            }
        	else
        		dst = &__fb_ctx.null_desc;
        }
        else
        	dst = &__fb_ctx.null_desc;
	}
	else
		dst = &__fb_ctx.null_desc;

	/* del if temp */
	fb_hStrDelTemp_NoLock( src );

	FB_STRUNLOCK();

	return dst;
}
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Question about MID$, and temporary string

Post by counting_pine »

Yes, Mid() will make a copy of the string data it extracts from the argument passed to it, and because you're assigning to a zstring, it will have to then copy that data again into the memory used by the zstring.

If it were assigning to a var-len string, AFAIK it probably wouldn't have to do that since the return value of (intrinsic?) string functions is marked as temporary, so the assignee string can just inherit the temporary string's data pointer.

I recently posted a hackish function which works a bit like Mid(), but eliminates the temporary copy of the string data. It might be useful for micro-optimisation:
http://www.freebasic.net/forum/viewtopi ... 70#p186770

I'll repost it here with a tailored example:

Code: Select all

function pFastMid(ps as const string ptr, start as integer, length as integer) as const string ptr
    static a(0 to 3-1) as integer

    a(0) = cint(strptr(*ps) + start-1)
    a(1) = length
    a(2) = length

    dim p as const string ptr = cptr(string ptr, @a(0))
   
    assert( sizeof(a(0)) * 3 = sizeof(string) ) '' a() same size as string?
    assert( strptr(*p) = a(0) )                 '' a(0) points to string data?
    assert( len(*p) = a(1) )                    '' a(1) is the string length?
    assert( *p = mid(*ps, start, length) )      '' return matches standard mid()?

    return p
end function

dim ReturnLine as zstring * 78

dim s as string = "Hello world"

ReturnLine = *pFastMid(@s, 4, 5)
write ReturnLine

if ReturnLine = "lo wo" then
   print "Success"
end if
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Question about MID$, and temporary string

Post by Josep Roca »

If you want to avoid the creation of temporary strings, then copy the memory directly:

Code: Select all

dim ReturnLine as zstring * 78
dim s as string = "Hello world"

DIM p1 AS UBYTE PTR = @ReturnLine
DIM p2 AS UBYTE PTR = STRPTR(s)
memcpy p1, p2 + 3, 5
p1[5] = 0
print ReturnLine
print len(ReturnLine)

memcpy p1, p2 + 2, 2
p1[2] = 0
print ReturnLine
print len(ReturnLine)
xlucas
Posts: 334
Joined: May 09, 2014 21:19
Location: Argentina

Re: Question about MID$, and temporary string

Post by xlucas »

Is memcpy part of FreeBasic? It's not in the wiki. Sounds to me like a C function, but then don't I need to #include anything? Is it available for all platforms?
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Question about MID$, and temporary string

Post by fxm »

See at:
C Standard Library Functions

You must specify the header:
#include "crt/string.bi"
Last edited by fxm on Oct 08, 2017 5:40, edited 1 time in total.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Question about MID$, and temporary string

Post by Josep Roca »

Yes, it is a C function.

#include once "crt/mem.bi"

> Is it available for all platforms?

Gues it is.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Question about MID$, and temporary string

Post by dodicat »

memcpy can be nearly simulated.
The difference is you have to use brackets when calling it.
memcpy()

Josep Roca's code + memcpy

Code: Select all


#macro memcpy(dest,src,size)
    for n as long=0 to (size)/sizeof(*(src))-1
        (dest)[n]=(src)[n]
    next
#endmacro


dim ReturnLine as zstring * 78
dim s as string = "Hello world"

DIM p1 AS UBYTE PTR = @ReturnLine
DIM p2 AS UBYTE PTR = STRPTR(s)
memcpy (p1, p2 + 3, 5) '<---------  use brackets
p1[5] = 0
print ReturnLine
print len(ReturnLine)

memcpy (p1, p2 + 2, 2)
p1[2] = 0
print ReturnLine
print len(ReturnLine)

sleep 
(In case your C runtime has broken down)
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Question about MID$, and temporary string

Post by Josep Roca »

> (In case your C runtime has broken down)

If the C runtime is broken, you won't be able to use FB.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Question about MID$, and temporary string

Post by dodicat »

That's true.
Maybe even Win 10 wouldn't fire up?
Can someone please test!
Post Reply