Thread: modify pointer to a string/character constant.

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    11

    modify pointer to a string/character constant.

    in c programming language.
    I have 1 question
    1)
    Code:
    #include <stdio.h>
    #include <string.h>
    int main()
    {
    
    char *x;
    char t[10]= "telephone";
    x=(char *)malloc( sizeof(char) *6  );
    x=t;
    printf("&#37;s\n",x);
    free(x);
    /* x[0]='t' will probably give segementation fault.. */
    printf("%s\n",x);
    return 0;
    
    }
    the output is:
    telephone
    telephone

    even though I had free(x);

    How do I properly free this, supposing I want the char *x to point to something else.
    For example say I have the string "telephone" and want it to be "zelephone"

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    char *x;
    char t[10]= "telephone";
    x=(char *)malloc( sizeof(char) *6  );  // why 6 ?
    x=t;        // this assignes x to the char array t, not an error but not a good idea
               // you have lost the pointer that malloc returned
    free(x);   // trying to free an array
    Use strcpy instead of assignement and allocate enough to hold the data.
    Kurt

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Accessing free()'d memory doesn't HAVE to cause a segmentation fault. It's simply undefined behavior, meaning anything can happen. BTW, you don't need to cast malloc(), and you should always #include <stdlib.h> when using malloc().

    FAQ > Explanations of... > Casting malloc

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    11
    If I stick to using strcpy to copy ... notice how here I can't and even strncpy can't work
    instead I would need concatenation of this new character to the rest of the string.
    I also tried char backup[strlen(s)+1]; it fails too.


    to try again..

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void replaceFirstCharacter(char *s,char replaceWith);
    int main()
    {
    
    char *x;
    char t[10]= "telephone";
    x=(char *)malloc( sizeof(char) *10  ); /*9 characters plus null byte.*/
    strcpy(x,t);
    /*so that it works with any string... changing the first character only*/
    replaceFirstCharacter(x,'z');
    
    
    printf("&#37;s\n",x);
    return 0;
    
    }
    
    void replaceFirstCharacter(char *s,char replaceWith)
    {
    char *backup;
    if (strlen(s) >=1)
    {
    backup=(char *)malloc( sizeof(char) * (strlen(s)+1));
    strcpy(backup,s);
    backup[0]=replaceWith; /*I guess I should somehow avoid this?*/
    strcpy(s,backup);
    
    }
    }
    Last edited by xsouldeath; 09-29-2007 at 02:24 PM.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You should include <stdlib.h> for malloc(), and avoid casting malloc() unless you prefer to do so for some reason.

    sizeof(char) is always 1, so you can leave it out of your expressions.

    Code:
    void replaceFirstCharacter(char *s,char replaceWith)
    {
    char *backup;
    if (strlen(s) >=1)
    {
    backup=(char *)malloc( sizeof(char) * (strlen(s)+1));
    strcpy(backup,s);
    backup[0]=replaceWith; /*I guess I should somehow avoid this?*/
    strcpy(s,backup);
    
    }
    }
    It seems to me that that function could be replaced with
    Code:
    void replaceFirstCharacter(char *s, char replaceWith) {
        if(strlen(s)) s[0] = replaceWith;
    }
    But anyway, if you really wanted to make s point to a different string, you'd need to pass in s as a char** pointer or return the modified s; because, as written, any changes to what s points to inside that function will not be reflected in the calling function.
    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
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Well let's be sure that we understand something here. If you just want to change the first character of whatever the user types than all you have to do is set up an array really, and then reassign the first character to 'z', or whatever.

    If you want to treat user input as a constant, than you would need to explicitly copy anything the user types into a new string before you make changes, with functions like strdup() or sprintf(). And then when you are done with the copy you can throw it away.

    But turning "telephone" into "zelephone" should be trivial work.

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    11
    Perhaps this will resolve my question once and for all!...
    I need to pass x to foo(char *s) and change it to "House".

    If possible I would like to keep the main program intact, and change only the foo function to accomplish
    this.

    oddly void foo(char *s) { strcpy(s,"House"); }
    somehow works even though it doesnt seem memory is allocated to it!


    the current output is(Notice how the pass by reference fails to show in the main program):

    before call:Fun
    In foo:House
    after call:Fun
    Code:
    #include <stdio.h>
    void foo(char *s);
    int main()
    {
    char x[4]="Fun";
    printf("before call:&#37;s\n",x);
    foo(x);
    printf("after call:%s\n",x);
    }
    
    /*sets a given string to "House"*/
    void foo(char *s)
    {
    free(s);
    s=(char *)malloc( 6 * sizeof(char));
    strcpy(s,"House");
    printf("In foo:%s\n",s);
    
    }
    Last edited by xsouldeath; 09-29-2007 at 06:04 PM.

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Well it can't be that different. Just create a new string and copy over what you need.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    
    char *foo( char str[], const char change_to[] )
    {
       void *temp;
       assert( str != NULL && change_to != NULL );
       temp = realloc( str, strlen( change_to ) + 1 );
       if ( !temp )
          return NULL;
       str = temp;
       strcpy( str, change_to );
       
       return str;
    }
    
    int main( void )
    {
       char *p = malloc( 4 );
       if( p ) {
          strcpy( p, "Fun" );
          if( foo( p, "House" ) )
             puts( p );
    
          free( p );
       }
       return 0;
    }
    Last edited by whiteflags; 09-29-2007 at 06:32 PM.

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    11
    okay, well I am not familiar with assert, so from a Google search, it looks like it gives errors if allocation fails.. anyways in
    foo()
    1)what exactly does str=temp; do?
    2)does it allocate str to be able to hold as much as temp does?
    or does it make str point to temp?

    3)which I guess char str[] could be rewritten as char * str ?

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Read about realloc. It can resize the allocated memory that a pointer points to, and in this case, I wanted to ensure that we had enough room to store the change_to string. But it's dubius just to reassign the pointer you gave realloc like here.

    p = realloc( p, SOME_SIZE );

    If realloc returns NULL and p pointed to some memory before, we would leak the old memory. So that's why I needed to use the temp pointer. I simply reassigned the str pointer after I was sure that realloc worked, and later returned it.

    Absolutely. In terms of function parameters, char *foo is char foo[], more or less.

  11. #11
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Code:
    void foo(char *s)
    {
    free(s);
    s=(char *)malloc( 6 * sizeof(char));
    strcpy(s,"House");
    printf("In foo:%s\n",s);
    
    }
    For this function to do what you want it to do, you need to pass a char** not a char*.
    The address of variable s in foo() is not the same as the address of variable x in main(). If you change the value of s, it will not change the value of x. You need to pass the address of x like this: foo( &x ); then dereference s in foo()...
    Something like this:
    Code:
    void foo( char** s )
    {
        char* temp = malloc( 6 );
    
        if ( temp != NULL )
        {
            strcpy( temp, "House" );
            free( *s );
            *s = temp;
        }
    }

  12. #12
    Registered User
    Join Date
    Sep 2007
    Posts
    11
    well I'm given the function prototype like I said... any ideas on how to solve this ...
    to have a
    void foo(char *s) that changes a string in the main program...
    It works when I use strcpy only... but when I use malloc and free it does not overwrite whats in the main... whats also bad
    is when I try to allocate a large string it fails.

    Code:
    #include <stdio.h>
    #include <stdlib.h> 
    void * foo(char *s);
    int main()
    {
    char x[3]="Hi";
    printf("before call:&#37;s\n",x);
    foo(x);
    printf("after call: %s",x);
    printf("\n");
    return 0;
    
    }
    
      void * foo (char *s)
    {
    /* How do I dynamically allocate memory for s here, so that it will change it in the main WITHOUT changing the function prototype or call*/
    free(s);
    s=(char *)malloc(31*sizeof(char));
    /*the above 2 statements fail. */
    strcpy(s,"hello how are you doing today.");  /*this works with a small string*/
    }

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    You can only free() what you got back from malloc()
    So initially, you need to start with a malloc if your function is going to call free

    Eg.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    void *foo(char *s); /* returning char* would be better */
    
    int main()
    {
        char *x = malloc(3);
        strcpy(x,"Hi");
        printf("before call:&#37;s\n", x);
        x = foo(x);
        printf("after call: %s", x);
        free(x);
        printf("\n");
        return 0;
    
    }
    
    void *foo(char *s)
    {
        free(s);
        s = malloc(31 * sizeof(char));
        strcpy(s, "hello how are you doing today.");
        return s;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. sorting the matrix question..
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-22-2008, 03:17 PM
  3. constant pointer?
    By thebudbottle in forum C Programming
    Replies: 3
    Last Post: 11-07-2004, 10:25 PM
  4. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM