-1

Hi i'm new in the world of C and there is something really odd about my code. The objective is to create a function that can trim a string with spaces and/or tabs at the beginnig and at the end. I cannot use String lib.

The problem is that there is a printf in my code just for testing and it does the job very well. But if i delete that printf the function doesn't work properly... Anyone can help me please?

Here's the code:

   #include <stdio.h>

short trim(short idx,char*str,short dir){   //gives the index to trim
    while(*(str+idx)==' ' || *(str+idx)=='\t')
        idx+=dir;
    return idx;
}

short findEnd(char *str){   // find the end of the string
    int ret=0;
    while(*(str+ret)!='\0')ret++;
    return ret-1;
}

char *strtrim(char *str){   //The function that trims the string
    short begin=trim(0,str,1);
    short end=trim(findEnd(str),str,-1)+1;
    char ret[end-begin];
    for (short i=begin; (i-begin)<sizeof(ret);i++){
        ret[i-begin]=*(str+i);
        printf("%d\n",i);// <--------------------------------this is the printf
    }
    char *c=&ret[0];
    return c;
}

int len(char *str){// return the length of the given string
    int ret=0;
    for(int i=0;*(str+i)!='\0';i++){
        printf("%d %c\n",i,*(str+i));// another printf for testing porpuses
        ret=i;
    }
    return ret;
}


int main(){
    char *str="     this is a great test to test your testing skills        ";
    printf("%d\n",len(strtrim(str)));
}

How can just a printf makes such a difference? If i use printf everytime i run it gives me the same and the correct output, however if i don't use the printf it gives me a totally different output eveytime i run it and it's always the wrong one

  • `strtrim` returns a pointer to a local variable. – Retired Ninja Mar 25 '17 at 17:36
  • Possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – Retired Ninja Mar 25 '17 at 17:37
  • Retired Ninja thank you for your reply. Yes strtrim return a pointer (sorry for that mistake). However my question has nothing to do with local variable memory (i think) it's about printf that makes a total diference. with printf eveything is fine everytime i run it but without that single printf everything goes wrong – Manuel Dias Mar 25 '17 at 19:43
  • Once you have undefined behavior, seemingly irrelevant changes can have unpredictable effects. Fix the UB, *then* worry about whether your corrected code behaves properly. – Keith Thompson Mar 25 '17 at 20:04
  • The printf makes the stack different perhaps making your array allocate differently. It's still wrong, but seems to work. The worst bugs. – Retired Ninja Mar 25 '17 at 20:43

1 Answers1

0

In strtrim, you use char ret[end-begin]; to assign to the return pointer value.

This is local memory, and hasn't the proper lifespan: it's made available to other parts of the program as soon as you exit the routine: undefined behaviour.

"it works when I insert/remove a printf" should be a red flag for this kind of mistake.

You can fix it like:

  • using strdup to return an actually allocated copy of your result
  • pass another parameter to be filled by the routine

Since you cannot change function prototype, just allocate inside the function. If you cannot use strdup or any copy function, you can still do it.

replace that code:

char ret[end-begin];

by the following:

char *ret = malloc(end-begin);

then return ret instead of c.

you have an allocated string now, don't forget to free it in the caller when you don't need it anymore.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219