Returning pointers to locally allocated memory

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • krreks
    New Member
    • Oct 2008
    • 22

    Returning pointers to locally allocated memory

    I know it's not "best practice" returning pointers to local variables, but in this case I think i need it.

    I'm writing a method to remove some characters at the beginning and some at the end of a string and return the result as a pointer to memory allocated in the function.

    I developed the function separately, it worked, but when implemented with the rest of the code it doesn't return anything... It seems that the letters is added to the var new, but when i try printing the string, nothing is returned....

    Code:
    char * prepareMessage(char str[]) {
    	int i=0, j=0, state=0;
    	
    	while(str[i]==' ') { i++; } //skip whitespace
    
    	while(state == 0 && str[i]!='\0') { //find the start of the message (after 'new ')
    		if(str[i]=='n' && str[i+1]=='e' && str[i+2]=='w' && str[i+3]==' ') {
    			state = 1;
    			i += 4;
    		}
    		i++;
    	}
    	
    	char * new = malloc(strlen(str)-i);
    	while(str[i]!='\0') { //copy the chars to the new var
    		*(new+j) = str[i++];
    		j++;
    	}
    	
    	if(*(new+j-1)=='\"') { //remove trailing " and append \0
    		*(new+j-1) = '\0';
    	} else { //no trailing " - something wrong, free mem and return NULL
    		free(new);
    		return NULL;
    		debug("ERROR: NO TRAILING \"");
    	}
    	
    	return new;
    }
    The str[] comes from

    Code:
    char inputBuffer[200] = "";
    fgets(inputBuffer, 200, stdin)
    Hope someone is able to point me in the right direction...

    Thanks in advance!
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    Just a few remarks:

    1) your first two while loops can be replaced by a single strstr() function call.
    2) your third while loop can be replaced by a single strcpy() function call.
    3) why do you use two notations? i.e. s[i] and *(s+i)

    kind regards,

    Jos

    Comment

    • krreks
      New Member
      • Oct 2008
      • 22

      #3
      Originally posted by JosAH
      Just a few remarks:

      1) your first two while loops can be replaced by a single strstr() function call.
      2) your third while loop can be replaced by a single strcpy() function call.
      3) why do you use two notations? i.e. s[i] and *(s+i)
      Code:
      char * prepareMessage(char str[]) {
      	int i=0;
      	char * new;
      	
      	char * pMsgStart = strstr(str, "new ");
      	if(pMsgStart!=NULL) {
      		int i = (strstr(str, "new ")-&str[0])+5;
      		new = malloc(strlen(str)-i);
      		strcpy(new, (str+i));
      		if(new[strlen(new)-1] == '"') {
      			new[strlen(new)-1] = '\0';
      			return new;
      		} else {
      			return NULL;
      		}
      	} else
      		return NULL;
      }
      Then the code is more compact and uses the built in functions (smart :). But I'm still not getting proper output... I think it might be the input that's not proper :s

      This is my testcase which makes it fail:

      Code:
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      char * prepareMessage(char str[]) {
      	int i=0, j=0, state=0;
      	char * new;
      	
      	char * pMsgStart = strstr(str, "new ");
      	if(pMsgStart!=NULL) {
      		int i = (strstr(str, "new ")-&str[0])+5;
      		new = malloc(strlen(str)-i);
      		strcpy(new, (str+i));
      		if(new[strlen(new)-1] == '"') {
      			new[strlen(new)-1] = '\0';
      			return new;
      		} else {
      			return NULL;
      		}
      	} else
      		return NULL;
      }
      
      int main() {
      	char inputBuffer[200];
      	
      	do { 
      		if(fgets(inputBuffer, 200, stdin)==0) {
      			strcpy(inputBuffer,"exit");
      		} else {
      			char * new = prepareMessage(inputBuffer);
      			printf("%s\n",new);
      			free(new);
      		}
      	} while (strcmp ("Apple",inputBuffer) != 0);
      	
      	
      	return 0;
      }
      K

      Comment

      • JosAH
        Recognized Expert MVP
        • Mar 2007
        • 11453

        #4
        You should malloc at least one byte more on line #12; the \0 character needs to
        be stored as well.

        kind regards,

        Jos

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #5
          ps. oh, and btw, the fgets() function also returns the end-of-line character(s) in
          the buffer so the last character can never be a double quote in your buffer.

          kind regards,

          Jos

          Comment

          • krreks
            New Member
            • Oct 2008
            • 22

            #6
            Originally posted by JosAH
            You should malloc at least one byte more on line #12; the \0 character needs to
            be stored as well.
            Ok. But it's not much use if nothing is returned... It's something with the fgets i think... If I use a plain array like this:

            Code:
            char inputBuffer[200] = "new \"message\"";
            char * new prepareMessage(inputBuffer);
            it works, but the value comes from fgets() like this:

            Code:
            char inputBuffer[200] = "";
            	char * tmp = malloc(200);
            	
            	do { 
            		if(fgets(tmp, 200, stdin)==0) {
            			strcpy(inputBuffer,"exit");
            		} else {
            			strcpy(inputBuffer, tmp);
            			char * new = prepareMessage(inputBuffer);
            			printf("%s\n",new);
            			free(new);
            		}
            	} while (strcmp ("Apple",inputBuffer) != 0);
            it's not working... Why!?

            Comment

            • krreks
              New Member
              • Oct 2008
              • 22

              #7
              Originally posted by krreks
              it's not working... Why!?
              I still don't know why, but this code seems to be working. Not 100% shure, but it gives me the right string every time :)

              Code:
              #include <stdio.h>
              #include <stdlib.h>
              #include <string.h>
              
              char * prepareMessage(char str[]) {
              	int i=0, j=0, state=0;
              	char * new;
              	
              	char * pMsgStart = strstr(str, "new ");
              	if(pMsgStart!=NULL) {
              		int i = (strstr(str, "new ")-&str[0])+5;
              		new = malloc(strlen(str)-i+1);
              		strcpy(new, (str+i));
              		if(new[strlen(new)-2] == '"') {
              			new[strlen(new)-2] = '\0';
              			return new;
              		} else {
              			return NULL;
              		}
              	} else {
              		return NULL;
              	}
              }
              
              int main() {
              	char inputBuffer[200] = "";
              	char * tmp = malloc(200);
              	
              	do { 
              		if(fgets(tmp, 200, stdin)==0) {
              			strcpy(inputBuffer,"exit");
              		} else {
              			strcpy(inputBuffer, tmp);
              			char * new = prepareMessage(inputBuffer);
              			printf("%s (%d chars long)\n",new, strlen(new));
              			free(new);
              		}
              	} while (strcmp ("Apple",inputBuffer) != 0);
              	
              	return 0;
              }

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #8
                Originally posted by krreks
                it's not working... Why!?
                Read my reply #5.

                kind regards,

                Jos

                Comment

                Working...