Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #24202 > unrolled thread
| Started by | Shriramana Sharma <jamadagni@gmail.com> |
|---|---|
| First post | 2012-08-04 07:12 -0700 |
| Last post | 2012-08-10 10:45 +0300 |
| Articles | 7 on this page of 27 — 11 participants |
Back to article view | Back to comp.lang.c
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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2012-08-05 08:15 +0200 |
| Subject | Re: 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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-08-05 10:22 +0100 |
| Subject | Re: 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]
| From | "Heinrich Wolf" <invalid@invalid.invalid> |
|---|---|
| Date | 2012-08-05 17:00 +0200 |
| Subject | Re: 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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-08-05 16:20 +0100 |
| Subject | Re: 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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2012-08-05 19:51 +0200 |
| Subject | Re: 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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-08-05 21:04 +0100 |
| Subject | Re: 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]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2012-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