LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-05-2013, 05:18 AM   #1
selvakumar.murugan
LQ Newbie
 
Registered: Dec 2013
Posts: 2

Rep: Reputation: Disabled
Angry Conditional jump or move depends on uninitialised value(s)


I have tried, all my usual methods. but never got around this problem. the isSeparator functions accepts a character and checks whether the character is one of the separators. and the token function does the the job of strtok. the functions works as intended. but valgrind keeps on showing these error messages.


>>> valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ../bin/tokenizer
==11897== Memcheck, a memory error detector.
==11897== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==11897== Using LibVEX rev 1658, a library for dynamic binary translation.
==11897== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==11897== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==11897== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==11897== For more details, rerun with: -v
==11897==
Menu
encode
decode
exit

Enter you choice: decode
Enter the morse string: selva kumar
token:selva
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x40132F: isSeparator (tokenizer.c:40)
==11897== by 0x401468: token (tokenizer.c:83)
==11897== by 0x40199C: ascii_string (morse.c:164)
==11897== by 0x40124E: main (main.c:77)
token:kumar
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x40132F: isSeparator (tokenizer.c:40)
==11897== by 0x4013D2: token (tokenizer.c:72)
==11897== by 0x40199C: ascii_string (morse.c:164)
==11897== by 0x40124E: main (main.c:77)
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x4A0679C: strcmp (mc_replace_strmem.c:341)
==11897== by 0x401832: ascii_string (morse.c:121)
==11897== by 0x40124E: main (main.c:77)
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x4A067CA: strcmp (mc_replace_strmem.c:341)
==11897== by 0x401832: ascii_string (morse.c:121)
==11897== by 0x40124E: main (main.c:77)
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x401835: ascii_string (morse.c:121)
==11897== by 0x40124E: main (main.c:77)
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x4A0679C: strcmp (mc_replace_strmem.c:341)
==11897== by 0x4018D4: ascii_string (morse.c:145)
==11897== by 0x40124E: main (main.c:77)
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x4A067CA: strcmp (mc_replace_strmem.c:341)
==11897== by 0x4018D4: ascii_string (morse.c:145)
==11897== by 0x40124E: main (main.c:77)
==11897==
==11897== Conditional jump or move depends on uninitialised value(s)
==11897== at 0x40190A: ascii_string (morse.c:143)
==11897== by 0x40124E: main (main.c:77)
sk
Menu
encode
decode
exit

Enter you choice: decode
Enter the morse string: ... . .-.. ...- .- -.- ..- -- .- .-.
token:...
token:.
token:.-..
token:...-
token:.-
token:-.-
token:..-
token:--
token:.-
token:.-.
SELVA KUMAR
Menu
encode
decode
exit

Enter you choice:
exit
==11897==
==11897== ERROR SUMMARY: 1675 errors from 8 contexts (suppressed: 4 from 1)
==11897== malloc/free: in use at exit: 0 bytes in 0 blocks.
==11897== malloc/free: 32 allocs, 32 frees, 791 bytes allocated.
==11897== For counts of detected errors, rerun with: -v
==11897== All heap blocks were freed -- no leaks are possible.


main.c
===============================
Code:
    /***************************************************************
    * FILE        : main.c
    *
    * DESCRIPTION :  accepts a string and prints out its morse code
    *            equivalent or accepts a morse code and print
    *            out its ascii equivalent.
    *
    **************************************************************/


    /**************************************************************
                        HEADERS
    **************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>

    #include "tokenizer.h"
    #include "morse.h"


    #define MAX 1024

    /*************************************************************
                        FUNCTIONS
    *************************************************************/

    char* getChoice()
    {
        char *choice = (char*)malloc(sizeof(*choice) * 16);
        memset(choice, 0, 16);
        printf("Menu\n");
        printf("encode\n");
        printf("decode\n");
        printf("exit\n");

        printf("\n Enter you choice: ");
        scanf("%s", choice);
        return choice;

    }

    int main()
    {

        char* choice = getChoice();
        while ( 0 != strcmp(choice, "exit"))
        {
                if (0 == strcmp(choice, "encode"))
                {
                        char str[MAX];
                        printf("Enter the alphabetical string: ");
                        while(getchar() != '\n');
                        fgets(str, sizeof(str), stdin);

                        int len = strlen(str);
                        str[len - 1] = '\0';

                        char *mor = morse(str, strlen(str));
                        printf("%s\n", mor);

                        free(choice);
                        free(mor);
                }

                else if (0 == strcmp(choice, "decode"))
                {
                        char mor[MAX];
                        printf("Enter the morse string: ");
                        while(getchar() != '\n');
                        fgets(mor, sizeof(mor), stdin);

                        int len = strlen(mor);
                        mor[len - 1] = '\0';

                        char *sstr = ascii_string(mor, strlen(mor));
                        printf("%s\n", sstr);

                        free(choice);
                        free(sstr);
                }
                choice = getChoice();
        }
        free(choice);
        return 0;

    }
morse.c
========================
Code:
    /******************************************************************
    * FILE        :  morse.c
    *
    * DESCRIPTION :  implements morse() and ascii_string() functions
    *
    ******************************************************************/


    /**************************************************************
                        HEADERS
    **************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>

    #include "morse.h"
    #include "tokenizer.h"


    #define MAX 1024

    /*************************************************************
                        FUNCTIONS
    *************************************************************/


    /*********************************************************************
    * Function  :       morse
    *
    * Description       :       accepts an ascii string, and returns the morse
    *                   equivalent of the string.
    *
    * Returns   :       morse code equivalent
    *********************************************************************/

    char g_morse[][5] = {                  ".-\0",        //A
                                   "-...\0",      //B
                                       "-.-.\0",      //C
                                       "-..\0",       //D
                                       ".\0",         //E
                                       "..-.\0",      //F
                                       "--.\0",       //G
                                       "....\0",      //H
                                       "..\0",        //I
                                       ".---\0",      //J
                                       "-.-\0",       //K
                                       ".-..\0",      //L
                                       "--\0",        //M
                                       "-.\0",        //N
                                       "---\0",       //O
                                       ".--.\0",      //P
                                       "--.-\0",      //Q
                                       ".-.\0",       //R
                                       "...\0",       //S
                                       "-\0",         //T
                                       "..-\0",       //U
                                       "...-\0",      //V
                                       ".--\0",       //W
                                       "-..-\0",      //X
                                   "-.--\0",      //Y
                                       "--..\0"};     //Z



    char* morse(char* str, int len)
    {
        char* mor = (char*)malloc(sizeof(*mor) * len * 4 + 1);
        int i = 0;
        int last = 0;
        while (i < len)
        {

                if (isspace(str[i]))
                {
                        mor[last] = ' ';
                        last++;
                        mor[last] = ' ';
                        last++;
                        i++;
                        continue;

                }


                if (!isalpha(str[i]))
                {
                        mor[last] = str[i];
                        last++;
                        mor[last] = ' ';
                        last++;
                        i++;
                        continue;
                }

                char* tmor = g_morse[toupper(str[i])-65];
                strcpy(mor + last, tmor);
                last += strlen(tmor);

                mor[last] =  ' ';
                last++;

                i++;
        }

        return mor;
    }

    char* ascii_string(char* str, int len)
    {
        char* ascii = (char*)malloc(sizeof(*ascii) * len + 1);
            char separator[] = " `~!@#$%^&*()_+=[]{}|\\:;\"'<,>/?\0";
        char* tok = token(str, separator, TOKEN_START);
        int flag = 0;
        int index = 0;
        char space[] = " \0";

        while (NULL != tok)
        {

                if (0 == strcmp(tok, space))
                {

                        if (flag == 1)
                        {
                                flag = 0;
                                ascii[index] = ' ';
                                index++;
                                flag = 0;

                        }
                        else
                        {
                                flag++;
                        }

                }


                else
                {
                        int i = 0; int ret = 1;
                        for(i = 0; (i < 26) && (ret != 0); i++)
                        {
                                ret  = strcmp(tok, g_morse[i]);
                        }

                        if ( i < 26 )
                        {
                                ascii[index] = i + 64;
                                index++;
                        }

                        else
                        {
                                ascii[index] = tok[0];
                                index++;
                        }

                        flag = 0;
                }

                free(tok);
                tok = token(str, separator, TOKEN_CONTINUE);

        }
        ascii[index-1] = '\0';
        return ascii;

    }
tokenizer.c
=======================================================
Code:
    /***************************************************************
     ** FILE        : tokenizer.c
     **
     ** DESCRIPTION : implements the token() function to separate tokens
     **
     **************************************************************/


     /**************************************************************
                        HEADERS
     **************************************************************/
     #include <stdio.h>
     #include <stdlib.h>
     #include "tokenizer.h"
     #include <string.h>


     #define TRUE 1
     #define FALSE 0
     /*************************************************************
                        FUNCTIONS
     *************************************************************/

     /************************************************************
      *
      * Function: isSeparator
      *
      * Description: accepts a characater, and list of separators
      *                  and returns TRUE if the character is in the
      *                  separator list.
      *
      ************************************************************/
     unsigned int isSeparator( char c, char* separator)
     {
        int len  = strlen(separator);
        int   i  = 0;
        while( i < len )
        {
                char t = separator[i];
                if( c == t)
                        return TRUE;
                i++;
        }
        return FALSE;
     }

     /******************************************************************
      *
      * Function    : token
      *
      * Description : accepts a string - which is to be tokenized
      *           and list of separator - which separates the token
      *                   and a token state whether to clear the previous session
      *           or to continue with the current string
      *
      * Returns     : the next token in the string.
      *
      ******************************************************************/
     char* token (char* text, char* separator, TokenState state)
     {
        static int pos = 0, len = 0;
        int prev = pos;
                char* tok = NULL;
        int tok_len = 0;

        if (TOKEN_START == state)
        {
                pos = 0;
                len = strlen (text);
        }

        if (isSeparator(text[pos], separator))
        {
                tok = calloc(sizeof(*tok) + 1, sizeof(*tok));
                tok[0] = text[pos];
                tok[1] = '\0';
                pos++;
                return tok;
        }

        while( pos < len && '\0' != text[pos] )
        {
                while (!isSeparator(text[pos], separator))
                        pos++;

                tok_len = pos-prev;
                tok = malloc(sizeof(*tok) * tok_len + 1);
                strncpy(tok, text+prev, tok_len);
                tok[tok_len] = '\0';

                printf("token:%s\n",tok);
                prev = pos - 1;
                return tok;
        }

        pos = 0;
        return NULL;

     }
tokenizer.h
=====================================
Code:
    #ifndef TOKENIZER__H
    #define TOKENIZER__H

    #define TRUE 1
    #define FALSE 0


    typedef enum _TokenState
    {
        TOKEN_START,
        TOKEN_CONTINUE
    }TokenState;

    char* token(char* src, char* separator, TokenState state );

    #endif /* TOKENIZER__H */
morse.h
======================================
Code:
    #ifndef MORSE__H
    #define MORSE__H

     char* morse(char* str, int len);
     char* ascii_string(char* str, int len);

    #endif /*MORSE__H*/
I have given all the related code. compile and run, and give me some pointers on it. why conditional jump error on valgrind occurs. what are the probable reasons for it to occur. thanks in advance.
 
Old 12-06-2013, 02:06 AM   #2
vvopenka
LQ Newbie
 
Registered: Sep 2006
Location: Prague
Distribution: Ubuntu 10.04
Posts: 18

Rep: Reputation: 1
I think that you've got an error in the main function on this line:
Code:
fgets(str, sizeof(str), stdin);
If you look into the specification of fgets function, especially into the return value it says:
Quote:
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
So theoretically if stdin is closed before you start reading it for the first time, fgets does not touch str at all and you are passing it to the morse function and all the way down to the jump uninitialized. You should always check that fgets didn't return NULL.
 
Old 12-06-2013, 06:59 AM   #3
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
I think even though it is not causing a compile error, maybe a warning, you should not have an un-dimensional g_morse array.

Rather than:
Code:
char g_morse[][5];
Have it instead as:
Code:
static char *g_morse[fixed-number] = { strings, ... };
Where the fixed number is the amount of initialized strings you have. From what I can see, line 145 in morse.c is
Code:
ret = strcmp(tok, g_morse[i]);
and this line may be causing the complaint.

I'd also recommend that when you compile, you turn on as many warnings as you can and also flag warnings as errors so that you have to resolve the warnings. Do not ignore compilation warnings unless you truly understand that they are not relevant to your case.

Recommended warning flags:
Code:
-Werror -Wall -Wextra -Wswitch-default -Wswitch-enum -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn
Further if you also put in -ggdb and -O0 you'll disable optimizations and compile for GDB friendly debug. And you can debug your code from within GDB, place a breakpoint at morse.c:145 and see what the problem is, live.
 
Old 12-06-2013, 08:38 AM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Code:
    char separator[] = " `~!@#$%^&*()_+=[]{}|\\:;\"'<,>/?\0";
C library str*() functions regard \0 as the end of string marker, but not part of the string itself (and any double quoted "string literal" automatically gets a \0 at the end). This means when you have
Code:
    int len  = strlen(separator);
It doesn't count the \0. So that

Code:
        while (!isSeparator(text[pos], separator))
            pos++;
goes right off the end of text.

Quote:
Originally Posted by rtmistler
Have it instead as:

Code:
static char *g_morse[fixed-number] = { strings, ... };
Where the fixed number is the amount of initialized strings you have.
I disagree that you should count the array elements, that's the compiler's job.
 
Old 12-16-2013, 12:06 PM   #5
rigor
Member
 
Registered: Sep 2003
Location: 19th moon ................. ................Planet Covid ................Another Galaxy;............. ................Not Yours
Posts: 705

Rep: Reputation: Disabled
You should also dimension the array properly. When this program is run:

Code:
# include <stdio.h>

/*  tsizeof_manual_term_str  */

int main(  int argc ,  char *argv[]  )
{
    printf(  "Bytes of memory taken by 'MANUALLY terminated' '5' byte string is:  %d.\n" ,  sizeof ( "1234\0" )  ) ;
    printf(  "Because the compiler automatically ADDS a 'null' terminator AFTER the\n"  ) ;
    printf(  "string which has been provided by the Human!\n"  ) ;
}
like this:

Code:
./tsizeof_manual_term_str
this is the output:

Code:
Bytes of memory taken by 'MANUALLY terminated' '5' byte string is:  6.
Because the compiler automatically ADDS a 'null' terminator AFTER the
string which has been provided by the Human!
So it really should be either

Code:
char g_morse[][6] =
etc., or get rid of the manually added \0 at the end of each string literal in the code to initialize the array. As have effectively already been pointed out, the \0 is not needed, even if you provide it, the compiler still automatically adds it's own terminator.
 
  


Reply

Tags
conditional, valgrind



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Conditional jump or move depends on uninitialised value(s) selvakumar.murugan Programming 1 12-05-2013 06:38 AM
Something depends on something else but something else is to be installed javascriptninja Linux - Newbie 3 02-05-2012 04:22 PM
[SOLVED] valgrind: Conditional jump or move depends on uninitialised value(s) golden_boy615 Programming 5 12-04-2011 02:32 AM
libpng Uninitialised Pointer Arrays Vulnerability win32sux Linux - Security 1 03-03-2009 05:44 PM
Partition size depends upon what ? tofee Linux - Newbie 2 03-23-2006 12:56 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:20 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration