Here comes Thomas !!

Welcome ..... :)

Thomas has patched the question in all possible scenarios. He is right 
..... one should make sure that one doesn't alter the contents of the 
read-only portions of memory. Normally 'constants' used in the program 
contribute towards the read-only portions.

Using memmove() will surely eliminate use of dynamic allocation and one 
may move the contents within the same memory-pool, thus making the 
implementation faster.


Thomas Hruska wrote:
> 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.
>
>   

Reply via email to