Help Returning char*

This is a discussion on Help Returning char* within the C Programming forums, part of the General Programming Boards category; I've written a function that will be called from a JNI method... It's been crashing, but I think it's working ...

  1. #1
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28

    Help Returning char*

    I've written a function that will be called from a JNI method... It's been crashing, but I think it's working now. Note the word 'think'..

    Does this seem right? If I don't use the copyTCHAR function it crashes...
    I'm not sure why it crashes either ... New to C and a little lost....


    Code:
    char* getDNSFullyQualifiedName()
    {
        TCHAR buffer[256] = TEXT("");
        DWORD dwSize = sizeof(buffer);
        char* temp;
    
        if (GetComputerNameEx((COMPUTER_NAME_FORMAT)3, buffer, &dwSize))
        {
             temp = copyTCHAR(buffer);
             dwSize = sizeof(buffer);
             ZeroMemory(buffer, dwSize);
             return temp;
        }
    
        return NULL;
    }

    Code:
    char* copyTCHAR(TCHAR* source)
    {
        int size;
        char* destination;
    
        if (!source)
        {
            return NULL;
        }
    
        size = strlen(source) + 1;
    
        if (size <= 0)
        {
            return NULL;
        }
    
        destination = (char *)malloc(size);
        strcpy(destination, source);
        return destination;
    }

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It didn't work before because you were trying to return a local array (that gets destroyed when the function exits, so the returned pointer becomes invalid immediately). The memory that you gain with malloc lives longer.

    An easier way may be to malloc the buffer in the first place.

    ZeroMemory is unneeded, because the buffer goes out of scope anyway.

    I don't know about the GetComputerNameEx, but since you pass a pointer to dwSize, may-be it would contain some useful information after the function call.
    Last edited by anon; 04-10-2007 at 03:24 PM.

  3. #3
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28
    If I understand you right .. the buffer would become invalid.

    Okay, makes sense...

    I need the value to stick around for a few other functions.

    If I return the pointer, created by copyTCHAR, I am okay, because I used
    malloc to initialize it?

    How do I use malloc within the function to get the name... the MSDN said
    to use a TCHAR .... I can't find an example that does. Can I use malloc on the TCHAR?

  4. #4
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    To achieve the same effect than what you have at the moment, you can change it like this:

    Code:
    TCHAR buffer[256] = TEXT("");
    
    // INTO
    
    TCHAR *buffer = malloc(256 * sizeof(*buffer));
    //or
    TCHAR *buffer = malloc(256 * sizeof(TCHAR));
    In your case, it was "ok" to omit the sizeof(char) part in malloc since the size of a char is 1 byte, which would give the same result.

  5. #5
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28
    Thank you!!!

    That works when testing in C -- but when I call it from the JNI method, it crashes out if I don't copy it.

    Any idea why?

  6. #6
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    Maybe try to post your current code.

  7. #7
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28
    Hmm... it appears to be working now. ) Thanks for all your help!!!!!

  8. #8
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28
    What am I doing wrong?

    I had:

    Code:
    void copy(char* destination, const char* source)
    {
        int length;
    
        if (!source)
        {
            return;
        }
    
        length = strlen(source);
    
        if (length == 0)
        {
            return;
        }
    	
        if (!destination)
        {
            destination = malloc(length + 1);	
        }	
    	
        strcpy(destination, source);
    }
    This works if the destination char* is already allocated to the right length.

    However, this does not work if I have to use malloc in the function. I returns NULL. I assume it goes out of scope.

    I need the function to make sure the destination is valid. So...

    Previous advice was to send in the pointer to the pointer if I had to use malloc. So I modified it to:

    Code:
    void copy(char** destination, const char* source)
    {
        int length;
    
        if (!source)
        {
            return;
        }
    
        length = strlen(source);
    
        if (length == 0)
        {
            return;
        }
    	
        if (!destination)
        {
            *destination = malloc(length + 1);	
        }	
    	
        strcpy(destination, source);
    }

    But that didn't work.

    I need a copy method that takes the two char* to be copied, allocates memory to the destination char*, and I would rather not have to return the char*.

    I would also like to handle the destination, if it was allocated to the wrong length before copy ... it will fail. Right?

    Help... please...

    I am so not having fun with pointers.

  9. #9
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,714
    A pointer is just like any other object. If you want to be able to use what it points to after the function call, you should return the pointer. See this thread

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by Deb View Post
    So I modified it to:

    Code:
    void copy(char** destination, const char* source)
    {
        int length;
    
        if (!source)
        {
            return;
        }
    
        length = strlen(source);
    
        if (length == 0)
        {
            return;
        }
    	
        if (!destination)
        {
            *destination = malloc(length + 1);	
        }	
    	
        strcpy(destination, source);
    }
    The strcpy() line should be:
    Code:
        strcpy(*destination, source);

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >    if (!destination)
    >    {
    >        *destination = malloc(length + 1);	
    >    }
    And the if() above is not what you want. You should probably take it out. You could make it:
    Code:
        if (!*destination)
    However you would then need to set destination to the null pointer in the calling function, the first time copy() is called:
    Code:
        char *destination = NULL;
        copy(&destination, source);

  12. #12
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28
    I read that link thanks..

    I'm still having issues...

    If I use malloc in the function, I should clean it up when I leave that
    function.

    I don't need the char* for anything else. I'm done with it.

    So I tried...

    Code:
    char* name = NULL;
    int length = strlen("input.txt");
    name = malloc(length + 1);
    strcpy(name, "input.txt");
    
    // Code here...
    
    if (name)
    {
        printf("calling free\n");
        free(name);
        printf("after free\n");
    }
    and it crashes when I exit the function. I have a printf statement before and after the free(name) call and it never prints the after free message.

    Any clue?

  13. #13
    Deb
    Deb is offline
    Registered User
    Join Date
    Apr 2007
    Posts
    28
    char *destination = NULL;
    copy(&destination, source);


    I believe that is what I want.

    I have quite a few functions that I don't want to keep assigning variables to.

    Seems so much easier to call copy with the two char* and not have a return
    assignment needed.

    For my copy() method, with errors fixed then:

    Code:
    void copy(char** destination, const char* source)
    {
        int length;
    
        if (!source)
        {
            return;
        }
    
        length = strlen(source);
    
        if (length == 0)
        {
            return;
        }
    	
        if (!*destination)
        {
            *destination = malloc(length + 1);	
        }	
    	
        strcpy(*destination, source);
    }
    And I wouldn't have to worry about the malloc, and could call the copy() method as:

    Code:
    char* destination = NULL;
    Code:
    copy(&destination, source);

    This leaves only one fail and that would be if the char* destination was allocated prior to the copy() method and there is not enough space for the source to be copied successfully; right?


  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by Deb View Post
    This leaves only one fail and that would be if the char* destination was allocated prior to the copy() method and there is not enough space for the source to be copied successfully; right?

    Right. Which is a pretty serious problem. One option is to do the memory allocation outside the function (before you call it), and use your first version of copy(), minus the malloc (which would be in the calling function). The reason is normally you also want to free the memory, so you'd have something like:
    Code:
    char *destination = NULL;
    
    /* Some sort of loop */
    
       destination = malloc(strlen(source)+1);
       copy(destination, source);
       /* More code which uses destination */
       free(destination);
    
    /* End of loop */
    But then the copy() function turns into a one line function. So what you could do is leave the malloc() in the function, make sure you do a free at the end of the loop in the calling function, and leave out the following if() in copy:
    Code:
        if (!*destination)
    However you'd need to set destination to NULL after free(), just in case the source was NULL as some point (which would result in a double free of destination). If source is an array, this may not even be possible, and you could leave out setting destination to NULL.

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    and it crashes when I exit the function. I have a printf statement before and after the free(name) call and it never prints the after free message.

    Any clue?
    That code looks fine, so it must be in the // Code here ... part.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stop GUI Application returning when run
    By DaveHope in forum Windows Programming
    Replies: 7
    Last Post: 06-29-2009, 08:57 PM
  2. function returning hour in either 12 or 24 hour format
    By stanlvw in forum C Programming
    Replies: 4
    Last Post: 01-01-2008, 05:02 AM
  3. Recursion: base case returning 1, function returning 0
    By yougene in forum C Programming
    Replies: 5
    Last Post: 09-07-2007, 05:38 PM
  4. Function returning incorrect value
    By CHurst in forum C Programming
    Replies: 3
    Last Post: 12-13-2005, 12:27 PM
  5. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21