char* doesn't work as intended

This is a discussion on char* doesn't work as intended within the C Programming forums, part of the General Programming Boards category; I am quite new to C, and for some reason, I can't get this following program to work as intended. ...

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    35

    char* doesn't work as intended

    I am quite new to C, and for some reason, I can't get this following program to work as intended. Can someone help me figure out why? Thanks in advance.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    void foo(char* source) {
            char random[] = "random";
            source = (char*)strdup(random);
    }
    
    int main() {
            char* source;
            foo(source);
            printf("%s\n", source); //Should say "random"
            return 0;
    }

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    If you want to change the value of a pointer in a called function, pass a pointer to the pointer. Just like if you wanted to change the value of an int in a called function you pass a pointer to an int.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    void foo(char** source) {
            char random[] = "random";
            *source = strdup(random);
    }
    
    int main() {
            char* source;
            foo(&source);
            printf("%s\n", source); //Should say "random"
            return 0;
    }
    And not everyone has the non-standard strdup. And there is no need for the cast.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    As Prelude would say, it might be easier to return the modified value than to deal with pointers-to-pointers ad infinitum.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    すまん Hikaru's Avatar
    Join Date
    Aug 2006
    Posts
    46
    foo doesn't look very useful. Maybe source should be where you get "random" and the function just returns the result of strdup?
    Code:
    #include <stdio.h>
    #include <string.h>
    
    char* modifiable(const char* source)
    {
        return strdup(source);
    }
    
    int main(void)
    {
        char* s = modifiable("random");
    
        printf("%s\n", s);
    
        return 0;
    }
    Also, C might not free memory at the end of the program and strdup uses malloc. You should free the memory when you're done. And I don't think strdup is a standard function, but it's not hard to write.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* strDup(const char* source)
    {
        char* result = malloc(strlen(source) + 1);
    
        if (result != NULL)
        {
            strcpy(result, source);
        }
    
        return result;
    }
    
    char* modifiable(const char* source)
    {
        return strDup(source);
    }
    
    int main(void)
    {
        char* s = modifiable("random");
    
        printf("%s\n", s);
        free(s);
    
        return 0;
    }
    But since all you're doing is returning the result of strdup, why not just use it in the first place?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* strDup(const char* source)
    {
        char* result = malloc(strlen(source) + 1);
    
        if (result != NULL)
        {
            strcpy(result, source);
        }
    
        return result;
    }
    
    int main(void)
    {
        char* s = strDup("random");
    
        printf("%s\n", s);
        free(s);
    
        return 0;
    }
    I don't think I like strdup. It's too hard to remember to free the memory.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* strDup(const char* source)
    {
        char* result = malloc(strlen(source) + 1);
    
        if (result != NULL)
        {
            strcpy(result, source);
        }
    
        return result;
    }
    
    int main(void) {
        strDup("");
        strDup(NULL);
    
        return 0;
    }
    Oops.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    すまん Hikaru's Avatar
    Join Date
    Aug 2006
    Posts
    46
    Oops.
    I'm sorry, I don't understand. Are you trying to tell me that my strDup is wrong? strDup("") works as it should and strDup(NULL) is a problem with the call, not the function. I should have added an assert in strDup though. Gomen.

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Sorry, I thought strdup did something special when passed NULL, but it doesn't; and the first example was intended to crash but it doesn't.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    すまん Hikaru's Avatar
    Join Date
    Aug 2006
    Posts
    46
    Sorry, I thought strdup did something special when passed NULL, but it doesn't; and the first example was intended to crash but it doesn't.
    Ah, thank you. I wasn't sure if there was a problem I was missing or not. Thank you for the help.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Hikaru
    I'm sorry, I don't understand. Are you trying to tell me that my strDup is wrong? strDup("") works as it should and strDup(NULL) is a problem with the call, not the function. I should have added an assert in strDup though. Gomen.
    Really though, you should fix it. It's easy:
    Code:
    char *strDup( char *s )
    {
        char *dup = NULL;
        if( s )
        {
            ...dupe it...
        }
        return dup;
    }
    Easy fix. I find it usually better to allow for stupid users, especially in cases like this where it's simple to do so.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    35
    Thanks for all the replies. Actually, I wrote the program in my initial post just as an example of the problem I was encountering in my larger program. In my larger one, I haven't been able to design it so that I can avoid double pointers. Anyways, Dave_Sinkula's first post corrected exactly what I needed to fix.

    As I'm looking through these other replies, I'm beginning to doubt my use of the strdup() function. I know that it's in glibc, but which C libraries don't have it? Should I really be using just str(n)cpy instead?

    Thanks again for all the replies.

  11. #11
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,528
    Well since strdup is not part of the C standard, you are obviously not guaranteed to find it on any implementation. If you think you are going to be building your code on a machine that does not support it, just write your own (as you have done) and don't worry about it. As far as using strcpy, if you end up having to malloc space every time you want to copy a new string, and if you have lots of instances of such a task in your code, why not just roll the work into one function (such as strdup), and be done with it?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strcmp returning 1...
    By Axel in forum C Programming
    Replies: 12
    Last Post: 09-08-2006, 08:48 PM
  2. getline() don't want to work anymore...
    By mikahell in forum C++ Programming
    Replies: 7
    Last Post: 07-31-2006, 11:50 AM
  3. Why don't the tutorials on this site work on my computer?
    By jsrig88 in forum C++ Programming
    Replies: 3
    Last Post: 05-15-2006, 11:39 PM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. DLL __cdecl doesnt seem to work?
    By Xei in forum C++ Programming
    Replies: 6
    Last Post: 08-21-2002, 05:36 PM

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