Roberto wrote:
> I wrote the following code to trim a char string at left. The code is
> simple and I think there is no error, but when I run, I get
> a "Segmentation fault". If I use the debugger (gdb), the error does
> not occur. May anyone help me to understand why? and where is the
> error?
> Thanks a lot.
> I am using a Red Hat distribution, version 7.3 and a cc release,
> version 2.96.
> == code start (ltrim.c) ==
> #include <errno.h>
> #include <string.h>
> /* ltrim() function
> * parameters:
> * string = the string to trim at left
> * return value:
> * char* : the trimmed string at left
> */
> char* ltrim(char *strn ){
> if (strn!=NULL) {
> char *p=strn;
> char *tmp_buffer = NULL;
> int l = strlen(p);
> printf( "ltrim() : [%p] [%s], len: %d \n", p, p, l);
>
> tmp_buffer = (char*) calloc( l+1, sizeof(char) );
> if (tmp_buffer!=NULL) {
> int x=0;
> char c='\0';
> printf("buffer before the filling: [%p] [%s] [%d]\n",
> tmp_buffer, tmp_buffer, strlen(tmp_buffer) );
> strcpy( tmp_buffer, p );
> printf("buffer after the filling with the string: [%p] [%s] [%d]
> \n", tmp_buffer, tmp_buffer, strlen(tmp_buffer) );
> while ( (c=tmp_buffer[x++])!=0 && c==' ' ) {
> printf("p: %d, c: [%c] 0X%2X\n",x, c, c);
> }
> printf( "reset string [%p], len: %d to 0\n", p, l );
> memset((void*)p, 0, l );
> printf("prepare the return parameter\n");
> strcpy(p, &tmp_buffer[x-1]);
> printf( "new string: [%s] l: %d -> free memory : [%p] [%s] [%d]
> \n", p, strlen(p), tmp_buffer, tmp_buffer, strlen(tmp_buffer) );
> free(tmp_buffer);
> tmp_buffer = NULL;
> printf( "memory freed\n");
> printf( "ltrim() : (trimmed) [%s], len: %d \n", strn, strlen
> (strn) );printf( "ltrim() : (trimmed) [%s], len: %d \n", strn, strlen
> (strn) );
> } else {
> printf( "ltrim() : cannot allocate memory [%s] \n", strerror
> (errno));
> }
> }
> printf("return the value\n");
> return (char*) strn;
> }
> int main (char **argz, char argc)
> {
> char *s0 = " bye 1 ";
> char *d0 = ltrim(s0);
> printf( "before: [%s] after [%s] \n", s0, d0 );
> exit(0);
> }
> == code end ====
Seeing as no one has actually provided a solution to the problem, I'll
reply.
1) You have a bunch of printf()'s in your code. Let's take those out.
> char* ltrim(char *strn ){
> if (strn!=NULL) {
> char *p=strn;
> char *tmp_buffer;
> int l = strlen(p);
>
> tmp_buffer = (char*) calloc( l+1, sizeof(char) );
> if (tmp_buffer!=NULL) {
> int x=0;
> char c='\0';
> strcpy( tmp_buffer, p );
> while ( (c=tmp_buffer[x++])!=0 && c==' ' ) {
> }
> memset((void*)p, 0, l );
> strcpy(p, &tmp_buffer[x-1]);
> free(tmp_buffer);
> } else {
> printf( "ltrim() : cannot allocate memory [%s] \n", strerror
> (errno));
> }
> }
>
> return (char*) strn;
> }
2) Crash probably occurs on the line with the strcpy(). This is
because only 2 bytes are allocated to tmp_buffer and p is an identical
pointer to the input string...which is more than two bytes.
3) This is a poorly implemented ltrim() function, IMO. You seem to
want to inline edit the string. You have no way of knowing if the
memory you are accessing to edit is in a static data segment (i.e.
read-only) or not. But it is odd that you are allocating memory for an
inline operation. Make up your mind.
4) Consider using Safe C++ - BString already has a fully-functional and
debugged LTrim() member. Or at least switch to C++.
5) If you insist on using C and inline editing, learn how to use
memmove() and drop all the dynamic allocation calls.
--
Thomas Hruska
CubicleSoft President
Ph: 517-803-4197
*NEW* VerifyMyPC 2.5
Change tracking and management tool.
Reduce tech. support times from 2 hours to 5 minutes.
http://www.CubicleSoft.com/VerifyMyPC/