Thread: Pass by reference crashed

  1. #1
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489

    Pass by reference crashed

    I'm trying to implement setLength procedure in C...

    But why it crashed when I call strlen??

    Code:
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    void setLength(char *string, int length)
    {
       string = (char *)malloc((length+ 1) * sizeof(char));
    
       int i = 0;
    
       for(; i<length; i++)
          string[i] = ' ';
    
       string[length] = '\0';
       
       //Doesn't crash!
       //printf("[%d]\n", strlen(str));
    }
    
    int main()
    {
       char *str;
    
       setLength(str, 10);
    
       //Crash!
       printf("[%d]\n", strlen(str));
    
       printf("[%s]", str);
    
       free(str);
    
       return 0;
    }
    Something wrong?

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    When you pass a variable to a function, you're really passing a copy. This means when you want to change a variable by passing it to another function, you must actually pass its address.

    So because you want to change the content of str, you must pass the address of str. And yes, that is a char **.

  3. #3
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147
    The following is the working code

    Code:
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    void setLength(char *string, int length)
    {
       string = (char *)malloc((length+ 1) * sizeof(char));
    
       int i = 0;
    
       for(; i<length; i++)
          string[i] = ' ';
    
       string[length] = '\0';
       
       //Doesn't crash!
       printf("in side function [%d]\n", strlen(string));
    }
    
    int main()
    {
       char *str;
    
       setLength(str, 10);
    
       //Crash!
       printf("Lenght :[%d]\n", strlen(str));
    
       printf("[%s]", str);
    
    //   free(str);
    
       return 0;
    }
    
    
    in side function [10]
    Lenght :[0]
    []

    i think problem here is you are trying to free memory which you assigned in the fucntion.

    btw i donot understand one thing why do want to put spaces inside the string in function.

  4. #4
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    That is "working code"? By what definition? It's certainly wrong.

  5. #5
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    To: MacGyver

    So because you want to change the content of str, you must pass the address of str. And yes, that is a char **.
    Code:
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    //Neither this function:
    
    void setLength(char **string, int length)
    {
       string = (char **)malloc((length+ 1) * sizeof(char));
    
       int i = 0;
    
       for(; i<length; i++)
          string[i] = (char *)' ';
    
       string[length] = (char *)'\0';
    }
    
    //Nor this function:
    
    void setLength2(char **string, int length)
    {
       *string = (char *)malloc((length+ 1) * sizeof(char));
    
       int i = 0;
    
       for(; i<length; i++)
          *string[i] = ' ';
    
       *string[length] = '\0';
    }
    
    //Still doesn't work T_T
    
    int main()
    {
       char *str;
    
       setLength((char **)&str, 10);
    
       //Crashed >_<!
       printf("Length :[%d]\n", strlen(str));
    
       printf("[%s]", str);
    
       //Doesn't matter with this...
       free(str);
    
       return 0;
    }
    To: vlrk

    btw i donot understand one thing why do want to put spaces inside the string in function.
    have you tried SetLength procedure in Delphi?

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    SetLength2() is correct. Try this syntax in your for loop:

    Code:
    (*string)[i]
    And of course the same change for adding the '\0'.

  7. #7
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147
    To: MacGyver

    i was just seeing on why the crash is happening ..!

    I have not checked the program in terms intended functionality ..


    I donot have delphi experience..

  8. #8
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489

    Smile Finished!

    To: Everybody

    Finally, the correct code is:

    Code:
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    void setLength(char **string, int length)
    {
       *string = (char *)malloc((length+ 1) * sizeof(char));
    
       int i = 0;
    
       for(; i<length; i++)
          (*string)[i] = ' ';
    
       (*string)[length] = '\0';
    }
    
    int main()
    {
       char *str;
    
       setLength(&str, 10);
    
       printf("Length: &#37;d\n", strlen(str));
       printf("[%s]", str);
    
       free(str);
    
       return 0;
    }
    The problem about passing arguments by value and by reference from pointer solved...

    Thanks a lot for vlrk and MacGyver for the cooperation in this thread.

    You are good guys! Thanks!

  9. #9
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    You have one error worth pointing out:

    Code:
    free(&str);
    Lose the & in this case, as it may cause program crashes in certain (perhaps most?) cases.

  10. #10
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Code:
    void setLength(char **string, int length)
    {
       free(*string);
    
       *string = (char *)malloc((length + 1) * sizeof(char));
    
       int i = 0;
    
       for(; i<length; i++)
          (*string)[i] = ' ';
    
       (*string)[length] = '\0';
    }
    free(*string);

    By the way, is it safe to do this?
    Or is there a way to dectect whether a variable is already allocated or not?

  11. #11
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by audinue View Post
    By the way, is it safe to do this?
    Or is there a way to dectect whether a variable is already allocated or not?
    There is no way to detect whether a pointer already has memory allocated. The usual convention is to set a pointer to NULL (in C) or to 0 (in C++) to indicate that the pointer does not reference any allocated memory.

    QuantumPete
    Edit:
    So you want something like this:
    Code:
    if (*string != NULL) {
       free (*string);
       *string = NULL;
    }
    Edit Edit:
    You should also test that the return value from malloc is not NULL (which indicates a memory problem) and don't cast the return type of malloc.
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by QuantumPete View Post
    The usual convention is to set a pointer to NULL (in C) or to 0 (in C++) to indicate that the pointer does not reference any allocated memory.
    I would have to disagree. It's a usual convention to set a pointer to NULL in both C and C++ to indicate that it does not reference to any allocated memory. Whether or not NULL is defined to 0 in C++ is irrelevant. Pointers are set to NULL and it's a good think to think like that since the next standard will introduce a keyword which will act as a null pointer.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    You should also test that the return value from malloc is not NULL (which indicates a memory problem) and don't cast the return type of malloc.
    I don't get it.
    Any example, please?

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    *string = (char *)malloc((length + 1) * sizeof(char));
    if (*string == NULL)
    {
        /* Do something */
    }
    Remove part in red.
    Add part in green.
    If malloc fails, it returns NULL. And if it returns NULL and you try to use that memory, you will mostly likely crash your program.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489

    Cool Some improvements

    Code:
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    //Simple macro :P
    
    #define $free(var) free(var); var = NULL;
    
    void setLength(char **string, int length)
    {
       if(*string != NULL)
       {
          $free(*string);
       }
    
       *string = malloc((length + 1) * sizeof(char));
    
       if(*string == NULL)
       {
          puts("ERROR: Could not allocated memory space.");
          exit(EXIT_FAILURE);
       }
    
       int i = 0;
    
       for(; i<length; i++)
          (*string)[i] = ' ';
    
       (*string)[length] = '\0';
    }
    
    int main()
    {
       char *str = NULL;
    
       int i = 0;
    
       for(; i<=16; i++)
       {
          setLength(&str, i);
    
          printf("Length: %d\n", strlen(str));
          printf("[%s]\n", str);
    
          $free(str);
       }
    
       return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. C OpenGL Compiler Error?
    By Matt3000 in forum C Programming
    Replies: 12
    Last Post: 07-07-2006, 04:42 PM
  5. how can i pass by reference by "malloc 2d array"?
    By Mathsniper in forum C Programming
    Replies: 10
    Last Post: 05-22-2005, 02:23 PM