Thread: Pointer passing between libraries

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    52

    Pointer passing between libraries

    Hi all,

    I'm puzzled...
    I've got a main function as follows:
    Code:
    ...
    int main()
    {
    
        char* cmdv[20];
        int i;
    	for(i=0;i<20;i++)
    	cmdv[i] = NULL;
        int cmdc = 0;
    	prompt_user(&cmdc, cmdv);
    
       	if(cmdc>0)
       	{
    ...
    prompt_user is a function defined in a static library as follows:
    Code:
    #include <stdio.h> //for NULL
    #include <unistd.h>
    #include <string.h>
    #define MAXSIZE 256
    
    void prompt_user(int *cmdc, char *cmdv[])
    {
                        char userInput[MAXSIZE];
    	    int nread;
    
    	    char *k;
    
    	    if(write(STDOUT_FILENO,"user: ",6)<0){
    		perror("write");
    		exit(1);
    	    }
    
    	    nread = read(STDIN_FILENO, userInput, MAXSIZE-1);
    
    	    if(nread<0){
    		perror("read");
    		exit(1);
    	    }
    
    	    userInput[nread] = '\0';
    
    		(*cmdc) = 0;
    		k = userInput;
    		while((cmdv[*cmdc]=(char*)strtok(k, " \n"))){
    		    k = NULL;
    		    (*cmdc)++;
    		}
    }
    The idea is that main calls prompt_user to fill in an array cmdv[].
    The thing that confuses me is that if I print cmdv[0] in the code for prompt_user, then I see what I typed in; however, if I print cmdv[0] in main after returning from the call to prompt_user, I see junk.
    main makes a call to itself in the end and oddly enough, the second time it runs it works properly (i.e. cmdv[0] has the expected value after returning from the call to prompt_user.

    If you need further information please let me know, the code for the main function is quite long because it compares the value of cmdv[0] to different strings so I didn't post the whole thing. Also, I don't want to post all of the main function because this is an assignment so I'm not allowed to post the whole thing of course...

    Is anybody able to see what's going on here?

    Thanks!

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The thing that I can see is that strtok returns a pointer relative to your LOCAL variable k and k is pointing to your LOCAL variable userInput. Therefore, when the function ends, k aka your cmdv, points to invalid addresses.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    the user input is stored in the local variable userInput

    cmdv pointers are set to point to different locations inside this buffer
    after the prompt_user function exits - local variable does not exists, so cmdv pointers are pointing to garbage, as you see it
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    52
    Oh.. I see... Anybody have any ideas of how I can modify the array with valid values but still use the the static library for prompt_user?
    Last edited by Canadian0469; 11-12-2007 at 07:58 AM.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can create your userInput buffer on the heap. Don't forget to release it after you're finished with it.
    HOWEVER, a better solution is pointed out by matsp. I suggest you heed that instead.
    Last edited by Elysia; 11-12-2007 at 10:05 AM.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Create your userInput buffer on the heap. Don't forget to release it after you're finished with it.
    Or simply pass in a buffer to the function - if you can hold it on the stack in one place, then it can be held on the stack somewhere else - and it saves trying to keep track of the allocations.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Might be a better solution, yes...
    I change my mind Go for mtsp's solution, it's the easiest and safest!

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Might be a better solution, yes...
    I change my mind Go for mtsp's solution, it's the easiest and safest!
    Of course, it also requires a second parameter of "maxsize". Otherwise it's definitely not safe.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Oct 2007
    Posts
    52
    Sorry but I'm not sure exactly how to implement matsp's solution...
    Do I do it by:

    1. Cutting char userInput[MAXSIZE]; from prompt_user and pasting it at the top of main()
    2. Changing prompt_user(&cmdc, cmdv); in main() to prompt_user(&cmdc, cmdv, userInput);
    3. Changing the definition of the prompt_user function to void prompt_user(int *cmdc, char *cmdv[], char userInput[])

    ?

    I tried this but I get a Segmentation fault... I have a feeling I'm making a pointer mistake because I still don't have a good understanding of pointers.

    Thanks for all the help so far!

  10. #10
    Registered User
    Join Date
    Oct 2007
    Posts
    52
    Forget what I said about the segmentation fault, it was just a silly logic mistake somewhere else in the code.

    Thanks so much everyone!!!!


  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Don't forget to pass the size of your array and check when getting your user input that you don't exceed the buffer size. That will be a security risk.
    Or you could go with C++ and use string classes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  3. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  4. passing a structure pointer by value
    By Bleech in forum C Programming
    Replies: 6
    Last Post: 07-11-2006, 05:58 PM
  5. Passing a function pointer to a templated type
    By skorman00 in forum C++ Programming
    Replies: 2
    Last Post: 04-13-2004, 08:31 PM