valgrind (Conditional jump or move depends on uninitialised value(s))

Hi everybody,

I wrote a small subroutine 'GetStringDelim()' to return a substring from a string enclosed by a string 'Limit1' and a char 'Limit2'. It works perfectly and I don't get an error message together with valgrind, if I set the 3rd parameter in GetStringDelim() to NULL (see below).

main()
{
   ...
   SubString = GetStringDelim(String,"small",NULL);
  ...   
}

But if I replace the third parameter with any character the code works as it is supposed to be, but I get the following message from valgrind:

==30534== 1 errors in context 1 of 1:
==30534== Conditional jump or move depends on uninitialised value(s)
==30534==    at 0x4023CA7: strlen (mc_replace_strmem.c:242)
==30534==    by 0x407D811: vfprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==30534==    by 0x4083362: printf (in /lib/tls/i686/cmov/libc-2.7.so)
==30534==    by 0x8048546: main (stringLTD.c:17)
==30534==  Uninitialised value was created by a heap allocation
==30534==    at 0x4022D78: malloc (vg_replace_malloc.c:207)
==30534==    by 0x8048636: GetStringDelim (stringLTD.c:60)
==30534==    by 0x8048530: main (stringLTD.c:15)

Does anyone has an idea what do I have to fix? Thanks!

Here is the complete code:

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

char *GetStringDelim(char *input, char *startstrg, char *limit);
char *GetString(char *input, char *string);

main()
{
   char *String="This is just a small example-string";
   char *SubString=NULL;

   printf("String %s\n",String);
   SubString = GetStringDelim(String,"small","-");
   printf("Substring:%s\n",SubString);
   
   free(SubString);
   
   return 0;
}

char *GetStringDelim(char *Input, char *Limit1, char *Limit2)
{
  int     Size = 0;
  char     *Start = NULL;
  char     *End = NULL;
  char     *String = NULL;
  int     i = 0;
  
  /* check input Limit1 */
  if(Limit1 == NULL)
  {
    Start = Input;
  }
  else
  {
    Start = GetString(Input,Limit1)+strlen(Limit1);
  }

  /* check input Limit2 */
  if(Limit2 == NULL)
  {
    String = (char*) malloc((strlen(Start)+1) * sizeof(char)); /* one more for NULL-char */
    strcpy(String,Start);

    return String;
  }
  else
    End    = strpbrk(Start,Limit2);
     
  /* get size of output string */
  Size = End - Start;
  
  if(Size <= 0)
    return NULL;
  
  /* copy string */
  String = (char*) malloc((Size+1) * sizeof(char)); /* one more for NULL-char */
  strncpy(String,Start,Size);

  return String;
}



char *GetString(char *input, char *string)
{
  char *in_incr=NULL, *str_incr=NULL;

  if ( !*string )
     return input;
  
  for (; *input; ++input ) 
  {
     if ( toupper(*input) == toupper(*string) ) 
     {
           for ( in_incr =input, str_incr = string; *in_incr && *str_incr; ++in_incr, ++str_incr )
           {
              if ( toupper(*in_incr) != toupper(*str_incr) )
         {
            break;
         }
      }
      
      if ( !*str_incr ) /* if current position is opposite of Nullstring (means 1) return start adress */
      {           
           return input; /* return the start of the match */
      }
     }
  }

  return NULL;
}

Why use valgrind for something that works correctly...so leave well enough alone. Only thing maybe to split up variable initializers like...

char *String="This is just a small example-string";

to something like

char s[]="This is just a small example-string";
char *String=s;

And #include <ctype.h> for toupper() calls.

Hey guys,

thanks for your help, but your proposals didn't resolve this issue. However, I decided to keep it like it is.

The point why I wanted solve the error messegae, which was provided by valgrind, is that the present subroutines are part of bigger code. That code gave me some strange results. I could resolve those bugs by use of valgrind. So I thought it might be a good idea to fix all problems in order to avoid future bugs.

By the way, more ideas are welcome... :smiley: