简体   繁体   中英

C++ while loop strange behaviour

I am writing a piece of code in C++ that takes a char array as input which contains a JSON-like text. The idea is to get the values from that JSON.

The function that is giving the error is the following:

variable * getVariableInfo(const char * variableInfo){
        /*get {...}*/
        printf("%s\n",variableInfo);
        int start, countWord=0;
        int order=-1, type=-1;
        char * value;
        variable * returnValue;
        const char * aux;
        while(*(variableInfo++)){
            if(*variableInfo=='"'){
                variableInfo++;
                aux=variableInfo;
                countWord=0;
                while(*(variableInfo++)!='"'){
                    countWord++;
                }
                char *word = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                strncpy(word, aux, countWord);
                word[countWord]='\0';
                printf("\nWORD %s", word);

                while(*(variableInfo++)!='"');
                aux=variableInfo;
                countWord=0;
                while(*(variableInfo++)!='"'){
                    countWord++;
                }
                char *str = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                strncpy(str, aux, countWord);
                str[countWord]='\0';
                printf("\nSTR %s\n",str);
                if(strcmp(word,ORDER)==0){
                        order=a2i(str);
                        printf("ORDER = %i", order);
                }
                /*TYPE*/
                else if(strcmp(word,TYPE)==0){
                        if(strcmp(str, valueINT)==0) type=TYPE_INT;
                        else if(strcmp(str, valueSTR)==0) type=TYPE_STRING;
                        else if(strcmp(str, valueBOOL)==0) type=TYPE_BOOLEAN;
                        else return 0;
                        printf("TYPE = %i", type);
                /*VALUE*/
                }
                else if(strcmp(word,VALUE)==0){
                        value =  (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                        strncpy(value, str, countWord);
                        value[countWord]='\0';
                        printf("VALUE = %s", value);
                }
                else{
                        printf("ELSE");
                        return 0;
                }
            }
            printf("\nCHAR %c\n---------", *variableInfo);
        }

        printf("Pass");
        if(type==-1||order==-1||!value){
            if(!type) printf("NOT");
            if(!order) printf("NOO");
            if(!value) printf("NOV");
            return 0;
        } 
        returnValue = (variable *) calloc(1,sizeof(variable)+(sizeof(char)*(strlen(value)+1)));
        returnValue->order=order;
        returnValue->type=type;
        strncpy(returnValue->value,value,strlen(value));
        returnValue->value[strlen(value)]='\0';
        return returnValue;
}

The var "variableInfo" is sent from another function and is created like following from the aux pointer which contains the original full JSON-like text:

variableInfo = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
strncpy(variableInfo, aux, countWord);
variableInfo[countWord]='\0';                               
variables[variableCount]=getVariableInfo(variableInfo);

As you can see, I added some printf and the output looks like the following:

{"ORDER":"0","TYPE":"int","VALUE":"9999"}

WORD ORDER
STR 0
ORDER = 0
CHAR ,
---------
WORD TYPE
STR int
TYPE = 0
CHAR ,
---------
WORD VALUE
STR 9999
VALUE = 9999
CHAR }
---------
CHAR 
Segmentation fault (core dumped)

I print the "variableInfo" variable and it shows the right piece of text that should be sent to the "getVariableInfo" function, then the values for ORDER, TYPE and VALUE are properly taken from the JSON-like text. However, I get the segmentation fault error, since the last round of the while, even if the last char is '\\0' it stays in the while loop (See output "CHAR }" should be last and next time that checks the while statement it should end it but it then prints "CHAR ").

Thanks for your help.

Kind regards.

You are using the post-increment operator to increment variableInfo . This operator returns a copy of the old pointer value, which does not point to \\0 . Use pre-increment instead:

while(*(++variableInfo))

Pre-increment will return the incremented value. See this question for more info on pre- and post-increment.

In this case if I would debug I might choose to store the original value of 'variableinfo' and print 'variableinfo-originalPointer' - to get a sensable index value.

I don't have a C compiler handy but I do wonder about your while loops: Perhaps

while (*(variableinfo++)=='"') 

Always increases 'variableinfo'. If that is so, it can be increased 3 times (three while-loops) before you check that the end of the string may be reached. If that is the case, it can go past the end of the string, never detecting that it crosses the end of the string.

Solutions: (1) tear the whileloops apart to make the increment explicit, and (2) Always check for '\\0' when you increase your string-pointer:

while(*variableinfo == '"' && *variableinfo!='\0')
{
    variableinfo++;
}

and possibly:

if ('\0' == *variableinfo)
    break;

to exit the outermost loop immediately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM