Thread: Malloc is it me or Malloc? ( or me ) How to...

  1. #1
    Banned
    Join Date
    Aug 2017
    Posts
    861

    Malloc is it me or Malloc? ( or me ) How to...

    I had this working, but it was only inserting one word into a string at given length using scanf.

    scanf only gets one word at a time. To eliminate that only one word limit unknown words wanted to be added to line thing. I replaced scanf with getline.

    now I am having problems getting a new char length of line1 + line2 + 1 using the method I used then went to malloc and still am getting a 0 (zero) on length using malloc to further modify the code to add more than one word into a string at given position.

    ( some comments in code to explaine as well )
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char * insertString(char* destination, int pos, char* sub_string)
    {
        printf("Destanation %s\n", destination);
        
        // gets 45 length
        printf("\nstrlen Destanation %lu\n\n", strlen(destination) );
        // gets whatever lenght input is
        printf("\nstrlen sub_string %lu\n\n", strlen(sub_string) );
        
        // add the two together plus one for \0
       // char HoldStr1[ (strlen(destination))+(strlen(sub_string))+1 ];
        
        //add the two together plus 1
        // gets 6
        printf("\n\nstrlen HoldStr1 %lu\n\n", strlen(HoldStr1) );
        
        //do it this way 
         
        int size_of_string = (strlen(destination))+(strlen(sub_string))+1;
    
        // gets 58 which = dest len + whatever input len is + 1
        printf("size of string %d\n",size_of_string );
        
        // do it this way gets zero lenght
        //char *HoldStr = (char *)malloc(size_of_string * sizeof(char));
        
        
        // do it this way size_of_string = 58
        char *HoldStr;
        HoldStr = (char *)malloc(size_of_string);
        //gets zero
        printf("\nstrlen HoldStr  %lu\n\n", strlen(HoldStr) );
        
    
    // cannot go any further until above is fixed. 
    // it now just returns the sub_string input as output 
    // like this
    
        strncpy(HoldStr,destination,pos);
        
        printf("1. HoldStr %s\n",HoldStr);
        
        HoldStr[pos] = '\0';
        
        strcat(HoldStr,sub_string);
        
        printf("2. HoldStr %s\n",HoldStr);
        
        strcat(HoldStr,destination+pos);
        
        printf("3. HoldStr %s\n",HoldStr);
        
        char *return_new_string;
        
        return_new_string = (char *)malloc(strlen(HoldStr)+1);
        
        strcpy(return_new_string,HoldStr);
        
    return return_new_string;    
        
    }
    
    
    int main (void)
    {
    
    char *string1 = "This is base string to insert something into.";
    //char string1[51];
    size_t buffer_size = 51;
    size_t charsAre;
    char *string2;
    //int ch;
    int insert = 0;
    
    string2 = (char *)malloc(buffer_size * sizeof(char));
    if ( string2 == NULL)
    {
        printf("Can't get buffer\n");
        exit(1);
    }
    printf("IN MAIN: StrLen %lu\n", strlen(string1) );
    
    //    printf("Enter your first string. No more than 50 chars long\n");
    
        //scanf("%s", string1);
        
        printf("enter a short string 50 max length,\nand a number where to put it too\n");
        
    //    ch = getchar(); // to try to stop scanf from skipping
    
        //scanf("%s %d", string2, &insert);
        
        charsAre =  getline(&string2, &buffer_size, stdin);
        
        printf("input charsAre %zu\n", charsAre);
        
        printf("IN MAIN str2: StrLen %lu\n", strlen(string2) );
        
        printf("String2 = %s\n", string2);
        
        //output    
        char *retur = insertString(string1, insert, string2);
        printf("Returned String: main: %s \n",  retur);
        
    return 0;    
    }
    if I go back to using just scanf it works just fine like that, but only one word again.

    I didn't start looking at strlen until after I started trying to expand on only one word inserts. So I must be missing something.
    Code:
    destination string 
    This is base string to insert something into.
    
    input string
    hello you 5
    
    output
    Returned String: main: This ihellos base string to insert something into. 
    

    Last edited by userxbw; 11-02-2017 at 10:03 AM.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,631
    scanf only gets one word at a time.
    If you used the proper format specifier scanf() can safely retrieve multiple word strings, you may want to read the documentation for this function to see how, and also never use scanf() to retrieve a string without specifying the proper limiting width to the format specifier.

    scanf only gets one word at a time. To eliminate that only one word limit unknown words wanted to be added to line thing. I replaced scanf with getline.
    Is there a reason you chose the non-C-standard getline() instead of using fgets() which is a standard C function?

    Do you know that getline() can allocate the required memory for you if you pass the correct parameters. And don't forget to free what you malloc.

    Also casting the return value from malloc() is considered a bad practice in C.

    Be careful with strcpy() and strcat() and the like, you need to make sure the destination array is large enough to hold the new strings.

  3. #3
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by jimblumberg View Post
    If you used the proper format specifier scanf() can safely retrieve multiple word strings, you may want to read the documentation for this function to see how, and also never use scanf() to retrieve a string without specifying the proper limiting width to the format specifier.


    Is there a reason you chose the non-C-standard getline() instead of using fgets() which is a standard C function?

    Do you know that getline() can allocate the required memory for you if you pass the correct parameters. And don't forget to free what you malloc.

    Also casting the return value from malloc() is considered a bad practice in C.

    Be careful with strcpy() and strcat() and the like, you need to make sure the destination array is large enough to hold the new strings.
    wow almost 7 minutes to get in here to reply after clicking reply.
    ok my getting strings input and manipulation with files and sdtin / stdout are not
    something I do in C programming. BASH ok but C I do a different type of Programming. I blame this sight as the cause of now learning how to deal with
    opening files and manipulating them. Not that it's a bad thing. I'm still getting
    use to it with familiarizing myself with all of the string functions. too many, they
    need to get rid of some more. my option.

    getline I just became familiar with it, I am Linux OS, so maybe that is why getline.
    scanf "specifying the proper limiting width to the format specifier."

    oh that now rings a bell, I've been using it to get one input at a time.

    I've been doing this with it.
    Code:
    scanf("%s %d %s", string1, int, string2);
    type methodology. So I told my brain, I need the whole line, getline was the first thing that popped into my brain, so I switch it to getline. Let me to piddle with the other two now. thanks.
    Be careful with strcpy() and strcat() and the like, you need to make sure the destination array is large enough to hold the new strings
    hence the malloc and the char var [strlen(dest) + strlen(sub_string) + 1 ];
    to get the proper size to strcat and strcpy

    PS yeah, freeing malloc that last one is a no go as far as I can see.
    Code:
    char *return_new_string;
        
        return_new_string = (char *)malloc(strlen(HoldStr)+1);
        
        strcpy(return_new_string,HoldStr);
        
    return return_new_string;
    if I free it before returning it what happens? cannot free it after return, because it has already left the function, cannot free it in main because it is a local var.

    program ends it gets freed. Nature of the beast.
    got a better Idea?
    Last edited by userxbw; 11-02-2017 at 11:18 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    > HoldStr = (char *)malloc(size_of_string);
    > //gets zero
    > printf("\nstrlen HoldStr %lu\n\n", strlen(HoldStr) );
    That's because conceptually at least, the memory returned by malloc is uninitialised.
    In your case, you got lucky and found a \0 in the first byte.
    It could have roamed through memory until the OS decided to kill the program with a segfault.

    This is how strlen works.
    It's the wrong way to find the length of allocated memory.
    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.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,631
    getline I just became familiar with it, I am Linux OS, so maybe that is why getline.
    I suggest you stick with standard C functions instead of using non-C-standard functions until you're more familiar with the language. The getline() function is at best a POSIX standard function and at worst a GCC specific function, stick to the standard C functions instead.

    cannot free it after return, because it has already left the function, cannot free it in main because it is a local var.
    Since you're returning the pointer, you can free the memory after the function.

    program ends it gets freed. Nature of the beast.
    got a better Idea?
    Avoid manual memory allocation unless it is absolutely necessary.

    In the case of your program you may want to just consider using a large statically allocated array instead of playing with manual memory management.

    And stop casting the return value of malloc(), that can mask serious problems.

  6. #6
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by jimblumberg View Post
    I suggest you stick with standard C functions instead of using non-C-standard functions until you're more familiar with the language. The getline() function is at best a POSIX standard function and at worst a GCC specific function, stick to the standard C functions instead.


    Since you're returning the pointer, you can free the memory after the function.
    so slapping a free(memory) in the function after the return frees a pointer created within same function?
    Avoid manual memory allocation unless it is absolutely necessary.
    char var[ strlen(size_string1)+ strlen(size_string2) + 1] wasn't seemingly working for me. It worked in another function I have, hummm
    back to the drawing board on this one.

    In the case of your program you may want to just consider using a large statically allocated array instead of playing with manual memory management.

    And stop casting the return value of malloc(), that can mask serious problems.
    char someString[99999999];

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,631
    so slapping a free(memory) in the function after the return frees a pointer created within same function?
    No, anything after a return statement is never executed. You're returning the pointer to the calling function, that's all that's needed to free the memory you allocated.

    char var[ strlen(size_string1)+ strlen(size_string2) + 1] wasn't seemingly working for me.
    Do you realize that in that code you're trying to use a Variable Length Array which is only truly supported in C99? Also remember that strlen() requires properly initialized and terminated C-strings.


    char someString[99999999];
    Well that size is a little excessive, but yes. Create the array in the calling function and pass it to your insert function.

  8. #8
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by jimblumberg View Post
    No, anything after a return statement is never executed. You're returning the pointer to the calling function, that's all that's needed to free the memory you allocated.
    that's what I'm talkin' a'bout..
    Code:
    in main 
        free(return_new_string);
    gets
    insert_string.c:103:8: error: 'return_new_string' undeclared (first use in this function)
    but I'm going to redo this anyways.
    Do you realize that in that code you're trying to use a Variable Length Array which is only truly supported in C99? Also remember that strlen() requires properly initialized and terminated C-strings.



    Well that size is a little excessive, but yes. Create the array in the calling function and pass it to your insert function.
    of course it is.

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,631
    that's what I'm talkin' a'bout..
    I'm glad "that's" what you're talking about, but could you be more vague? What exactly are you talking about?

    in main
    free(return_new_string);
    What makes you think you should free "return_new_string"? Where, in main, is a variable with that name even defined?

    Look at your function call:
    Code:
    char *retur = insertString(string1, insert, string2);
    What is the purpose of retur?

  10. #10
    Banned
    Join Date
    Aug 2017
    Posts
    861
    , anything after a return statement is never executed.

    What makes you think you should free "return_new_string"? Where, in main, is a variable with that name even defined?

    Look at your function call:
    Code:

    ?
    1 char *retur = insertString(string1, insert, string2);
    that's what I was thinking a'bout takin' a' bout.
    but I'm redoing everything so I don't think that will even be there anymore.
    Last edited by userxbw; 11-02-2017 at 04:36 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Malloc - when to use?
    By farukyaz in forum C Programming
    Replies: 5
    Last Post: 10-15-2011, 11:31 AM
  2. Replies: 7
    Last Post: 05-19-2010, 02:12 AM
  3. Replies: 7
    Last Post: 10-01-2008, 07:45 PM
  4. When and when not to use malloc()?
    By John.H in forum C Programming
    Replies: 5
    Last Post: 03-24-2003, 06:00 PM
  5. How do i use malloc?
    By Josh Kasten in forum C++ Programming
    Replies: 4
    Last Post: 02-24-2003, 11:44 PM

Tags for this Thread