Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #24202 > unrolled thread

Trying to figure out how to dynamically re-allocate strings while concatenating

Started byShriramana Sharma <jamadagni@gmail.com>
First post2012-08-04 07:12 -0700
Last post2012-08-10 10:45 +0300
Articles 7 on this page of 27 — 11 participants

Back to article view | Back to comp.lang.c


Contents

  Trying to figure out how to dynamically re-allocate strings while concatenating Shriramana Sharma <jamadagni@gmail.com> - 2012-08-04 07:12 -0700
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2012-08-04 16:17 +0200
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2012-08-04 16:22 +0200
      Re: Trying to figure out how to dynamically re-allocate strings while concatenating Shriramana Sharma <jamadagni@gmail.com> - 2012-08-04 07:25 -0700
        Re: Trying to figure out how to dynamically re-allocate strings while concatenating Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-08-04 16:04 +0100
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating "Heinrich Wolf" <invalid@invalid.invalid> - 2012-08-04 16:29 +0200
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-04 10:52 -0400
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating pete <pfiland@mindspring.com> - 2012-08-04 12:27 -0400
      Re: Trying to figure out how to dynamically re-allocate strings while concatenating Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-04 13:56 -0400
        Re: Trying to figure out how to dynamically re-allocate strings while  concatenating pete <pfiland@mindspring.com> - 2012-08-04 17:12 -0400
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating pete <pfiland@mindspring.com> - 2012-08-04 12:42 -0400
      Re: Trying to figure out how to dynamically re-allocate strings while concatenating Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-04 14:00 -0400
      Re: Trying to figure out how to dynamically re-allocate strings while concatenating Keith Thompson <kst-u@mib.org> - 2012-08-04 17:00 -0700
        Re: Trying to figure out how to dynamically re-allocate strings while concatenating pete <pfiland@mindspring.com> - 2012-08-04 20:48 -0400
        Re: Trying to figure out how to dynamically re-allocate strings while concatenating Jens Gustedt <jens.gustedt@loria.fr> - 2012-08-05 09:22 +0200
          Re: Trying to figure out how to dynamically re-allocate strings while concatenating Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-08-05 12:49 +0100
            Re: Trying to figure out how to dynamically re-allocate strings while concatenating Jens Gustedt <jens.gustedt@loria.fr> - 2012-08-05 17:12 +0200
            Re: Trying to figure out how to dynamically re-allocate strings while concatenating Keith Thompson <kst-u@mib.org> - 2012-08-05 13:17 -0700
              Re: Trying to figure out how to dynamically re-allocate strings while concatenating Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-08-05 22:53 +0100
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating Shriramana Sharma <jamadagni@gmail.com> - 2012-08-04 19:20 -0700
    Re: C Vs Asm i use for cat function "io_x" <a@b.c.invalid> - 2012-08-05 08:15 +0200
      Re: C Vs Asm i use for cat function "BartC" <bc@freeuk.com> - 2012-08-05 10:22 +0100
        Re: C Vs Asm i use for cat function "Heinrich Wolf" <invalid@invalid.invalid> - 2012-08-05 17:00 +0200
          Re: C Vs Asm i use for cat function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-08-05 16:20 +0100
        Re: C Vs Asm i use for cat function "io_x" <a@b.c.invalid> - 2012-08-05 19:51 +0200
          Re: C Vs Asm i use for cat function "BartC" <bc@freeuk.com> - 2012-08-05 21:04 +0100
    Re: Trying to figure out how to dynamically re-allocate strings while concatenating Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-08-10 10:45 +0300

Page 2 of 2 — ← Prev page 1 [2]


#24241 — Re: C Vs Asm i use for cat function

From"io_x" <a@b.c.invalid>
Date2012-08-05 08:15 +0200
SubjectRe: C Vs Asm i use for cat function
Message-ID<501e0e0e$0$17946$4fafbaef@reader1.news.tin.it>
In reply to#24202
"Stefan Ram" <ram@zedat.fu-berlin.de> ha scritto nel messaggio
news:check-20120804172635@ram.dialup.fu-berlin.de...
> Shriramana Sharma <jamadagni@gmail.com> writes:
>>Can anyone kindly point me to what I am doing wrong with realloc?
>
>  The result of an attempt should always be checked according
>  to me. The »free« below is not really required for this
>  small program, but would be helpful in many cases, where the
>  code is repeatedly executed in a program.
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> char * strapp( char * * const a, char const * const b )
> { *a = realloc( *a, 1 + strlen( *a )+ strlen( b ));
>  if( *a )strcat( *a, b );
>  return *a; }
>
> int main( void )
> { char const * const name_ = "my name is";
>  char * name = malloc( strlen( name_ )+ 1 );
>  if( name )
>  { strcpy( name, name_ );
>    if( strapp( &name, " this or " ))
>    if( strapp( &name, "that." ))
>    printf( "%s\n", name );
>    free( name ); }}
----------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define  u32  unsigned
#define  u8   unsigned char
#define  P    printf

u32 __stdcall asmcat(u8**  dove, u8* cosa);

int  main(void)
{u8   *name=0;
 u32      res;
 res=asmcat(&name, "123 prova");
 P("[%s] len=%u len1=%u\n",  (name?name:"NULL"), res, (u32) strlen(name));
 res=asmcat(&name, " 456 ");
 P("[%s] len=%u len1=%u\n",  (name?name:"NULL"), res, (u32) strlen(name));
 free(name);
 return 0;
}
-----------------
; nasmw -fobj      asmfile.asm
; bcc32 -v name.c  asmfile.obj
section _DATA use32 public class=DATA

extern _realloc
global asmcat

section _BSS  use32 public class=BSS
section _TEXT use32 public class=CODE

; u32 __stdcall asmcat(u8**  dove, u8* cosa)
; 0k,4j,8i,12b,16ra, 20P_dove, 24P_cosa
          align   4
asmcat:
          push    ebx
          push    esi
          push    edi
          push    ebp
;iint3
          mov     edi,  dword[esp+  20]
          mov     esi,  dword[esp+  24]
          cmp     edi,  0
          je      .e
          cmp     esi,  0
          je      .e
          jmp     short  .1
.e:       mov     eax,  -1
          stc
          jmp     .z
.1:       mov     edx,  esi
          jmp     short  .3
.2:       inc     edx
          jz      .e
.3:       cmp     byte[edx],  0
          jne     .2
          sub     edx,  esi
          mov     ebp,  edx
          mov     edx,  [edi]
          mov     ebx,  0
          cmp     edx,  0
          je      .6
          jmp     short  .5
.4:       inc     edx
          jz      .e
.5:       cmp     byte[edx],  0
          jne     .4
          sub     edx,  [edi]
          mov     ebx,  edx
.6:       mov     ecx,  ebx
          add     ecx,  ebp
          jc      .e
          add     ecx,  2
          jc      .e
          mov     edx,  [edi]
          push    ecx
          push    edx
          call    _realloc
          add     esp,  8
          cmp     eax,  0
          je      .e
          cmp     dword[edi],  0
          jne     .7
          mov     byte[eax],  0
.7:       mov     [edi],  eax
          mov     edx,  eax
          jmp     short  .9
.8:       inc     edx
.9:       cmp     byte[edx],  0
          jne     .8
          mov     ecx,  edx
          sub     ecx,  eax
          cmp     ecx,  ebx
          jne     .e
          mov     eax,  0
          add     ebx,  ebp
          jc      .e
          add     ebp,  2
          jc      .e
.a:       mov     al,  [esi]
          mov     [edx],  al
          inc     esi
          inc     edx
          dec     ebp
          jz      .e
          cmp     eax,  0
          jne     .a
          mov     eax,  ebx
          clc
.z:
          pop     ebp
          pop     edi
          pop     esi
          pop     ebx
          ret     8

          ret
-----------------

section _DATA use32 public class=DATA

extern  _realloc
global   asmcat

section _BSS  use32 public class=BSS
section _TEXT use32 public class=CODE

; u32 __stdcall asmcat(u8**  dove, u8* cosa)
; 0k,4j,8i,12b,16ra, 20P_dove, 24P_cosa
align  4
asmcat:
<b,i,j,k
  ;iint3
    j=^20|i=^24|j==0#.e|i==0#.e|#.1
.e: a=-1 |stc  |##.z
.1: r= i |#.3
.2: ++r  |jz .e
.3: B*r#.2
    r-=i |k=r
    r=*j |b=0|r==0#.6|#.5
.4: ++r  |jz .e
.5: B*r#.4
    r-=*j|b=r
.6: c=b  |c+=k|jc .e|c+=2|jc .e
    r=*j |_realloc<(r, c)|a==0#.e
    D*j==0!#.7|B*a=0
.7: *j =a|r=a |#.9
.8: ++r
.9: B*r#.8
    c=r|c-=a|c!=b#.e|a=0|b+=k|jc .e|k+=2|jc .e
.a: al=*i|*r=al
    ++i  |++r |--k|jz .e|a#.a
    a=b  |clc
.z:
>b,i,j,k
ret 8

ret


in few words: i prefer the above version even
it can be seem a little covoluted-difficult



[toc] | [prev] | [next] | [standalone]


#24250 — Re: C Vs Asm i use for cat function

From"BartC" <bc@freeuk.com>
Date2012-08-05 10:22 +0100
SubjectRe: C Vs Asm i use for cat function
Message-ID<jvle1q$g1g$1@dont-email.me>
In reply to#24241
"io_x" <a@b.c.invalid> wrote in message
news:501e0e0e$0$17946$4fafbaef@reader1.news.tin.it...

> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> #define  u32  unsigned
> #define  u8   unsigned char
> #define  P    printf
>
> u32 __stdcall asmcat(u8**  dove, u8* cosa);
>
> int  main(void)
> {u8   *name=0;
> u32      res;
> res=asmcat(&name, "123 prova");
> P("[%s] len=%u len1=%u\n",  (name?name:"NULL"), res, (u32) strlen(name));
> res=asmcat(&name, " 456 ");
> P("[%s] len=%u len1=%u\n",  (name?name:"NULL"), res, (u32) strlen(name));
> free(name);
> return 0;
> }
> -----------------
> ; nasmw -fobj      asmfile.asm
> ; bcc32 -v name.c  asmfile.obj
> section _DATA use32 public class=DATA
>
> extern _realloc
> global asmcat
>
> section _BSS  use32 public class=BSS
> section _TEXT use32 public class=CODE
>
> ; u32 __stdcall asmcat(u8**  dove, u8* cosa)
> ; 0k,4j,8i,12b,16ra, 20P_dove, 24P_cosa
>          align   4
> asmcat:
>          push    ebx
>          push    esi
>          push    edi
>          push    ebp
> ;iint3
>          mov     edi,  dword[esp+  20]
>          mov     esi,  dword[esp+  24]
>          cmp     edi,  0
>          je      .e
>          cmp     esi,  0
>          je      .e
>          jmp     short  .1
> .e:       mov     eax,  -1
>          stc
>          jmp     .z
> .1:       mov     edx,  esi
>          jmp     short  .3
> .2:       inc     edx
>          jz      .e
> .3:       cmp     byte[edx],  0
>          jne     .2
>          sub     edx,  esi
>          mov     ebp,  edx
>          mov     edx,  [edi]
>          mov     ebx,  0
>          cmp     edx,  0
>          je      .6
>          jmp     short  .5
> .4:       inc     edx
>          jz      .e
> .5:       cmp     byte[edx],  0
>          jne     .4
>          sub     edx,  [edi]
>          mov     ebx,  edx
> .6:       mov     ecx,  ebx
>          add     ecx,  ebp
>          jc      .e
>          add     ecx,  2
>          jc      .e
>          mov     edx,  [edi]
>          push    ecx
>          push    edx
>          call    _realloc
>          add     esp,  8
>          cmp     eax,  0
>          je      .e
>          cmp     dword[edi],  0
>          jne     .7
>          mov     byte[eax],  0
> .7:       mov     [edi],  eax
>          mov     edx,  eax
>          jmp     short  .9
> .8:       inc     edx
> .9:       cmp     byte[edx],  0
>          jne     .8
>          mov     ecx,  edx
>          sub     ecx,  eax
>          cmp     ecx,  ebx
>          jne     .e
>          mov     eax,  0
>          add     ebx,  ebp
>          jc      .e
>          add     ebp,  2
>          jc      .e
> .a:       mov     al,  [esi]
>          mov     [edx],  al
>          inc     esi
>          inc     edx
>          dec     ebp
>          jz      .e
>          cmp     eax,  0
>          jne     .a
>          mov     eax,  ebx
>          clc
> .z:
>          pop     ebp
>          pop     edi
>          pop     esi
>          pop     ebx
>          ret     8
>
>          ret
> -----------------
>
> section _DATA use32 public class=DATA
>
> extern  _realloc
> global   asmcat
>
> section _BSS  use32 public class=BSS
> section _TEXT use32 public class=CODE
>
> ; u32 __stdcall asmcat(u8**  dove, u8* cosa)
> ; 0k,4j,8i,12b,16ra, 20P_dove, 24P_cosa
> align  4
> asmcat:
> <b,i,j,k
>  ;iint3
>    j=^20|i=^24|j==0#.e|i==0#.e|#.1
> .e: a=-1 |stc  |##.z
> .1: r= i |#.3
> .2: ++r  |jz .e
> .3: B*r#.2
>    r-=i |k=r
>    r=*j |b=0|r==0#.6|#.5
> .4: ++r  |jz .e
> .5: B*r#.4
>    r-=*j|b=r
> .6: c=b  |c+=k|jc .e|c+=2|jc .e
>    r=*j |_realloc<(r, c)|a==0#.e
>    D*j==0!#.7|B*a=0
> .7: *j =a|r=a |#.9
> .8: ++r
> .9: B*r#.8
>    c=r|c-=a|c!=b#.e|a=0|b+=k|jc .e|k+=2|jc .e
> .a: al=*i|*r=al
>    ++i  |++r |--k|jz .e|a#.a
>    a=b  |clc
> .z:
>>b,i,j,k
> ret 8
>
> ret
>
>
> in few words: i prefer the above version even
> it can be seem a little covoluted-difficult

It's more than a little convoluted. The OP said they'd also used Python:

name = "my name is"

name += " this or "
name += "that."

print name

Do you still prefer your version (in whatever language it's in)?

The nearest you can get in C is to forget about dynamic allocation, and use
an upper limit for the size of the name. In lot of cases (99% of the ones
where I need to use string append), this is quite adequate, when you are
confident the results will not overflow:

#include <stdio.h>
#include <string.h>

#define maxnamesize 250

int main(void){
char name[maxnamesize];

strcpy(name,"my name is");
strcat(name," this or ");
strcat(name,"that.");

puts(name);

}

sprintf() can also be used for building strings this way. Otherwise using
all this memory management to, for example, build a string a character at a
time, is overkill. And will generate clutter if the result needs checking in
the caller's code.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#24271 — Re: C Vs Asm i use for cat function

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2012-08-05 17:00 +0200
SubjectRe: C Vs Asm i use for cat function
Message-ID<jvm1ph$rgp$1@news.m-online.net>
In reply to#24250
"BartC" <bc@freeuk.com> schrieb im Newsbeitrag 
news:jvle1q$g1g$1@dont-email.me...

...

> The nearest you can get in C is to forget about dynamic allocation, and 
> use
> an upper limit for the size of the name. In lot of cases (99% of the ones
> where I need to use string append), this is quite adequate, when you are
> confident the results will not overflow:

This is what I did in almost every program in my job.

> #include <stdio.h>
> #include <string.h>
>
> #define maxnamesize 250
>
> int main(void){
> char name[maxnamesize];
>
> strcpy(name,"my name is");
> strcat(name," this or ");
> strcat(name,"that.");
>
> puts(name);
>
> }

But strcat() is dangerous. It may result in a buffer overflow. In the 
programs, which I made in my job, I did it like that:

#define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1)
strcpy(name, "");
STRNCAT(name, "my name is");
STRNCAT(name, " this or ");
STRNCAT(name, "that.");

It works great and you need not clutter your code with error handling. It is 
just consuming some CPU cycles more than efficient code, which would not 
step through the length of a two times. 

[toc] | [prev] | [next] | [standalone]


#24274 — Re: C Vs Asm i use for cat function

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-08-05 16:20 +0100
SubjectRe: C Vs Asm i use for cat function
Message-ID<0.b96af505b8866ca088ae.20120805162011BST.87d3351i38.fsf@bsb.me.uk>
In reply to#24271
"Heinrich Wolf" <invalid@invalid.invalid> writes:

> "BartC" <bc@freeuk.com> schrieb im Newsbeitrag
> news:jvle1q$g1g$1@dont-email.me...
>
> ...
>
>> The nearest you can get in C is to forget about dynamic allocation,
>> and use
>> an upper limit for the size of the name. In lot of cases (99% of the ones
>> where I need to use string append), this is quite adequate, when you are
>> confident the results will not overflow:
>
> This is what I did in almost every program in my job.
>
>> #include <stdio.h>
>> #include <string.h>
>>
>> #define maxnamesize 250
>>
>> int main(void){
>> char name[maxnamesize];
>>
>> strcpy(name,"my name is");
>> strcat(name," this or ");
>> strcat(name,"that.");
>>
>> puts(name);
>>
>> }
>
> But strcat() is dangerous. It may result in a buffer overflow. In the
> programs, which I made in my job, I did it like that:
>
> #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1)
> strcpy(name, "");
> STRNCAT(name, "my name is");
> STRNCAT(name, " this or ");
> STRNCAT(name, "that.");
>
> It works great and you need not clutter your code with error
> handling. It is just consuming some CPU cycles more than efficient
> code, which would not step through the length of a two times. 

Unfortunately it goes silently wrong if the code refers to a point
rather than to an array (e.g. if you move the code into a function where
name is a parameter, it all goes wrong).

You can guard against that using tricks like this:

  #define STRNCAT(a, b) \
    (am_i_an_array(&a), strncat(a, b, sizeof(a) - strlen(a) - 1))

  static inline void am_i_an_array(char (*ap)[]) { return; }

though I feel sure there must be neater ways to it.  C11's _Generic, if
it gets widely implemented, would be one way.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#24277 — Re: C Vs Asm i use for cat function

From"io_x" <a@b.c.invalid>
Date2012-08-05 19:51 +0200
SubjectRe: C Vs Asm i use for cat function
Message-ID<501eb144$0$13283$4fafbaef@reader2.news.tin.it>
In reply to#24250
"BartC" <bc@freeuk.com> ha scritto nel messaggio
news:jvle1q$g1g$1@dont-email.me...
> "io_x" <a@b.c.invalid> wrote in message
> news:501e0e0e$0$17946$4fafbaef@reader1.news.tin.it...
>> in few words: i prefer the above version even
>> it can be seem a little covoluted-difficult
>
> It's more than a little convoluted. The OP said they'd also used Python:
>
> name = "my name is"
>
> name += " this or "
> name += "that."
>
> print name
>
> Do you still prefer your version (in whatever language it's in)?

yes, if my version called in a cpp file in operator= or +=
it can assume the above apparence but i could debug it, add one
error sys to it etc

i don't know how many error there are in the nasm version
but i prefer it to all C cat()s smart one, one can find...
i say nobody can write in C some cat function better
than that 'asmcat'...

> The nearest you can get in C is to forget about dynamic allocation, and use
> an upper limit for the size of the name. In lot of cases (99% of the ones
> where I need to use string append), this is quite adequate, when you are
> confident the results will not overflow:

adeguate... there is no way, for the king, in informatic :)

> #include <stdio.h>
> #include <string.h>
>
> #define maxnamesize 250
>
> int main(void){
> char name[maxnamesize];

and if the size is >250? you have to change the number in the file...
and if the string is going from extern?

> strcpy(name,"my name is");
> strcat(name," this or ");
> strcat(name,"that.");
>
> puts(name);
>
> }


[toc] | [prev] | [next] | [standalone]


#24285 — Re: C Vs Asm i use for cat function

From"BartC" <bc@freeuk.com>
Date2012-08-05 21:04 +0100
SubjectRe: C Vs Asm i use for cat function
Message-ID<jvmjq0$701$1@dont-email.me>
In reply to#24277
"io_x" <a@b.c.invalid> wrote in message 
news:501eb144$0$13283$4fafbaef@reader2.news.tin.it...
>
> "BartC" <bc@freeuk.com> ha scritto nel messaggio

>> The nearest you can get in C is to forget about dynamic allocation, and 
>> use
>> an upper limit for the size of the name. In lot of cases (99% of the ones
>> where I need to use string append), this is quite adequate, when you are
>> confident the results will not overflow:
>
> adeguate... there is no way, for the king, in informatic :)

A str_append() function as proposed by the OP, I tested to be about 3 times 
*slower* than Python. Usually C is some fifty times faster than Python.

But mainly it introduces extra complexity, and opportunities for bugs and 
memory leaks, if it is used where a fixed string size is viable.

>> #include <stdio.h>
>> #include <string.h>
>>
>> #define maxnamesize 250
>>
>> int main(void){
>> char name[maxnamesize];
>
> and if the size is >250? you have to change the number in the file...
> and if the string is going from extern?

If a fixed upper limit is not possible, then you use a different approach. 
But only if necessary.

(What if you need to do arithmetic on two integers, do you worry about the 
result not fitting into 32 or 64 bits? You don't use an arbitrary precision 
integer library just in case! In Python of course numbers will just get 
wider as needed. In C you need to use a more primitive approach, to retain 
an advantage.)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#24392

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-08-10 10:45 +0300
Message-ID<87vcgr42ce.fsf@bazspaz.fatphil.org>
In reply to#24202
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> Shriramana Sharma <jamadagni@gmail.com> writes:
> >Can anyone kindly point me to what I am doing wrong with realloc?
> 
>   The result of an attempt should always be checked according
>   to me. The »free« below is not really required for this
>   small program, but would be helpful in many cases, where the
>   code is repeatedly executed in a program.
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> 
> char * strapp( char * * const a, char const * const b )
> { *a = realloc( *a, 1 + strlen( *a )+ strlen( b ));
>   if( *a )strcat( *a, b );

Else? The memory *a used to point to will, however, still be
allocated, but you no longer have a reference to it. That's a leak.

>   return *a; }

The caller already knows what *a is, you don't need to tell
him twice. (This is a redundancy in some of the standard 
library too, in particular in the str functions.)

Phil
-- 
> I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.c


csiph-web