Thread: returning char arrays!!!!

  1. #1
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    122

    returning char arrays!!!!

    OK! ...Basically, I thought you could return a character array using the prototype char ** methodName() BUT, this doesn't work for my function!!!! Maybe I am doin something very wrong somewhere!!!! ...Well, here is my function......

    NOTE: This is a part of my university coursework! It is a coursework to implement a client and server to comply with the coffeepot protocol, HTCPCP!!!
    This is the propfind function for my server!!!! ...Its not complete, but I really need to find out how to return the char array "theMessage" to the calling function!!!

    Code:
    /***********************************************************************************/
    /* FUNCTION TO BUILD A PROPFIND RESPONSE FOR THE CLIENTS PROPFIND REQUEST          */
    /* RETURNS: A POINTER TO A CHAR ARRAY THAT CONTAINS THE RESPONSE MESSAGE           */
    /*    NOTE: WILL RETURN "NULL" IF THERE WAS AN ERROR IN BUILDING RESPONSE!!!       */
    /***********************************************************************************/
    char ** propfindRequest(char * requestDetail, char * clientIP) {
      
      char theMessage[MAXBUFF];      /* VARIABLE TO STORE THE SERVER RESPONSE MESSAGE */
      char potNoS[2];                /* STORE THE POT NUMBER IN STRING FORMAT */
      int potNo;                     /* STORE THE POT NUMBER IN INTEGER FORMAT */
      
      /* WHICH PROPFIND IS CLIENT SENDING??? */
      if (strcasecmp(requestDetail, "SERVER") == 0) { /* PROPFIND ON SERVER */
        if (sprintf(theMessage, "%s %sServer Properties:\nCoffeepot server version: %s\nNumber of coffeepots: %d\r\n", VERSION, OK, VERSION, POTS) < 0) {
          /* ERROR BUILDING RESPONSE! */
          printf("ERROR! Could not build a response for client (%s)\n", clientIP);
          strcpy(theMessage, "NULL");
          return theMessage;
        }
        else {
          printf("(%s) SENT A PROPFIND REQUEST (SERVER)\n", clientIP);
          return theMessage;
        }
      }
      else if (strncasecmp(requestDetail, "POT-", 4) == 0) {   /* PROPFIND REQUEST FOR POT-X */
        
        /* FIND OUT THE COFFEEPOT NUMBER CLIENT WISHES TO PROPFIND */              
        if (requestDetail[5]) { /* POT NUMBER IS DOUBLE FIGURES (ABOVE 9) */
          char potNoS[2];
          potNoS[0] = requestDetail[4];
          potNoS[1] = requestDetail[5];
          potNo = atoi(potNoS);          /* CONVERT FROM ASCII TO INT */
        }
        else if ((requestDetail[5]) && (requestDetail[6])) { /* POT NUMBER IS TRIPPLE FIGURES OR MORE - DEFINATLEY NOT SUPPORTED BY THIS SERVER */
          potNo = -1; /* SET TO INVALID POT NUMBER */
        }
        else { /* POT NUMBER IS SINGLE FIGURES */
          potNo = requestDetail[4];
          potNo -= '0';              /* CONVER FROM CHAR TO INT */
        }
        /* IS THE POT NUMBER VALID? */
        if ((potNo <= 0) || (potNo > POTS)){
          /* BUILD THE PROPFIND RESPONSE MESSAGE */
          if (sprintf(theMessage, "%s %sERROR! No such coffeepot (pot-%d) exists on this server!\r\n", VERSION, SERVICE_UNAVAILABLE, potNo) < 0) {
    	/* AN ERROR BUILDING RESPONSE */
            printf("ERROR! Could not build response for client (%s)\n", clientIP);
            strcpy(theMessage, "NULL");
            return theMessage;
          }
          else {
            /* AN INVALID PROPFIND REQUEST WAS SENT! */
            printf("(%s) JUST SENT AN INVALID PROPFIND REQUEST (POT-%d)\n", clientIP, potNo);
            return theMessage;
          }
        }
        else {
          bzero(theMessage, MAXBUFF);
          /* RESPOND TO CLIENT WITH THE PROPERTIES OF THE REQUESTED POT! */
          if (sprintf(theMessage, "%s %sProperties for POT-%d\nCan store %d cup(s) of coffee\nContains %d cups of coffee\r\n", 
    		  VERSION, OK, potNo, FULL, theMachine.coffeepots[potNo - 1]) < 0) {
            /* AN ERROR BUILDING RESPONSE */
    	printf("ERROR! Could not build response for client (%s)\n", clientIP);
            strcpy(theMessage, "NULL");
            return theMessage;
          }
          else {
            return theMessage;
          }
        }
        /* BAD PROPFIND REQUEST */
        else {
          /* RESPOND TO CLIENT */
          if (sprintf(theMessage, "%s %s ERROR! Un-Recognised PROPFIND request!\r\n", VERSION, BAD_REQUEST) < 0) {
    	/* AN ERROR BUILDING RESPONSE!!! */
            printf("ERROR! Could not build response for client (%s)\n", clientIP);
            strcpy(theMessage, "NULL");
            return theMessage;
          }
          else {
            return theMessage;
          }
        }
      }
    } /* propfindRequest() */
    There is also a syntax error, but ignore this as all i need to know is how to return the char array!!!!!

    here is the output from the compiler as it stands....

    Code:
    cd ~/socket/
    gcc -o server server.c
    server.c: In function `propfindRequest':
    server.c:218: warning: return from incompatible pointer type
    server.c:218: warning: function returns address of local variable
    server.c:222: warning: return from incompatible pointer type
    server.c:222: warning: function returns address of local variable
    server.c:248: warning: return from incompatible pointer type
    server.c:248: warning: function returns address of local variable
    server.c:253: warning: return from incompatible pointer type
    server.c:253: warning: function returns address of local variable
    server.c:264: warning: return from incompatible pointer type
    server.c:264: warning: function returns address of local variable
    server.c:267: warning: return from incompatible pointer type
    server.c:267: warning: function returns address of local variable
    server.c:271: error: syntax error before "else"
    server.c:277: warning: return from incompatible pointer type
    server.c:277: warning: function returns address of local variable
    server.c:280: warning: return from incompatible pointer type
    server.c:280: warning: function returns address of local variable
    server.c: At top level:
    server.c:283: error: syntax error before '}' token
    server.c: In function `main':
    server.c:442: warning: passing arg 2 of `propfindRequest' makes pointer from integer without a cast
    server.c:442: error: too many arguments to function `propfindRequest'
    
    Compilation exited abnormally with code 1 at Thu Mar 30 12:55:39
    Many thanks, Matt.

  2. #2
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    122
    OK!!! ...It seems that I have found a temporary way to solve this problem....

    Code:
    char * propfindRequest() {
      char * tmp;
      tmp = theMessage;
      return tmp;
    }

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    char ** propfindRequest(char * requestDetail, char * clientIP)
    {
        char theMessage[MAXBUFF];
        char potNoS[2];
        int potNo;
      
        if (strcasecmp(requestDetail, "SERVER") == 0)
        {
            if (sprintf(theMessage, "%s %sServer Properties:\nCoffeepot server version: "
                        "%s\nNumber of coffeepots: %d\r\n", VERSION, OK, VERSION, POTS) < 0)
            {
                printf("ERROR! Could not build a response for client (%s)\n", clientIP);
                strcpy(theMessage, "NULL");
                return theMessage;
            }
            else
            {
                printf("(%s) SENT A PROPFIND REQUEST (SERVER)\n", clientIP);
                return theMessage;
            }
        }
    
        ...
    This is what is causing all those "function returns address of local variable" and "return from incompatible pointer types" warnings. The theMessage variable is basically of type char* and the return type of the function is char**. Also, you cannot (or rather would never want to) return the address of a local variable. Local variables are allocated (pushed onto the stack) when the function is called and deallocated (popped off the stack) when the function exits. When you enter the propfindRequest function, space for theMessage is allocated. You then try to return the address of that memory location and the function ends which makes that memory position that you presumably have a pointer to somewhat meaningless. Anything else later on in your code (another function call perhaps) can overwrite that memory location that once belonged to theMessage with other random data that the new function might be allocating on the stack.

    You might be able to get away with it because by some chance, the memory doesn't get overwritten immediately after exiting the function, but odds are that it eventually will leaving you wondering why the data is now junk when it was fine just a couple of lines earlier in the code. Even you pointer solution doesn't work... you are still returning the address of a local variable (theMessage) that may/may not get wiped out.

    Code:
    else
    {
        bzero(theMessage, MAXBUFF);
        if (sprintf(theMessage, "%s %sProperties for POT-%d\nCan store %d cup(s) of coffee"
                    "\nContains %d cups of coffee\r\n", VERSION, OK, potNo, FULL, theMachine.coffeepots[potNo - 1]) < 0)
        {
            printf("ERROR! Could not build response for client (%s)\n", clientIP);
            strcpy(theMessage, "NULL");
            return theMessage;
        }
        else
        {
            return theMessage;
        }
    }
    else
    {
        if (sprintf(theMessage, "%s %s ERROR! Un-Recognised PROPFIND request!\r\n", VERSION, BAD_REQUEST) < 0)
        {
            printf("ERROR! Could not build response for client (%s)\n", clientIP);
            strcpy(theMessage, "NULL");
            return theMessage;
        }
        else
        {
            return theMessage;
        }
    }
    Like the error message says, "server.c:271: error: syntax error before "else"". That first else either needs to be an if/else, or the last else needs to be made into an if. ...or maybe something else needs to be done to rework that.

    It also looks like you might not be returning a value from the function in the case that requestDetail does not equal "SERVER" or "POT-" which might be the source of the "syntax error before "}" token" message although I have not looked to closely at that.

    In the end, to pass a string safely back to the caller, you have a few options. You can pass in the buffer as an argument to the function and then write whatever message to the passed in buffer. You could make theMessage static. You could dynamically allocate memory in the propfindRequest function and return that address as the return value of the function (although now the caller is responsible for the freeing of that allocated memory).
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. get keyboard and mouse events
    By ratte in forum Linux Programming
    Replies: 10
    Last Post: 11-17-2007, 05:42 PM
  3. The Interactive Animation - my first released C program
    By ulillillia in forum A Brief History of Cprogramming.com
    Replies: 48
    Last Post: 05-10-2007, 02:25 AM
  4. Need help understanding info in a header file
    By hicpics in forum C Programming
    Replies: 8
    Last Post: 12-02-2005, 12:36 PM
  5. AnsiString versus char *
    By Zahl in forum C++ Programming
    Replies: 35
    Last Post: 10-16-2002, 08:38 PM