Thread: Using malloc() with entered strings.

  1. #1
    Registered User
    Join Date
    Jul 2014
    Posts
    50

    Using malloc() with entered strings.

    Write a program to read in 6 strings from the keyboard, and then print them in reverse order on the screen, using the following directions. "Reverse order" means that if you enter six words, the sixth word will be printed first, the fifth will be printed second and so on.

    The strings will be stored in an array of 6 char pointers. The array should be declared as: char *str_array[6];

    This type of array only stores pointers to a string, and nor the strings themselves. You must allocate space for each string using malloc().

    Hint: If p is a pointer to a character, and n is the amount of storage you wish to allocate , then use the statement: p = (char*)malloc(n*sizeof(char));

    Now, I'm just trying to allocate memory for a single string and I can't even get that right. The program just crashes. If you look at my strlen() function inside malloc() I think that's what the problem could be because I know str_array is just the address of the first element. However, when I attempt to use the indirection operator *, the compiler warns it must be a constant char, so I declare the str_array to be a constant char pointer and it still doesn't like it.


    And how do I use the tab button when writing code, it just sends the cursor to "trackback" below text window everytime I try and use it.
    Code:
    #include <stdio.h>
    Code:
    #include <stdlib.h>
    #include <string.h>
    int main(void)
    {
        
    char *str_array;
    
    printf("Enter a string:\n");
    
    scanf("%s", str_array);
    
     
    /* Request storage & point to block of allocated memory */
    
    /* Strlen() to compute the length of entered string */
    
    str_array = (char*)malloc(strlen(str_array)*sizeof(char));
    
    printf("The string you entered was: %s", str_array);
    
     
    return 0;
        
    }
    
    


  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You have some apples that you want to place in a box, but you do not have any boxes. So, you put the apples into the box, and then you go to the store and buy the box of the right size. Sounds strange? But that's akin to what you're doing now:
    Code:
    char *str_array;
    
    printf("Enter a string:\n");
    
    scanf("%s", str_array);
    You declared a pointer to char and then requested for user input. You read the user input into the array via the pointer... but you don't have an array. You then request for storage so as to have an array:
    Code:
    str_array = (char*)malloc(strlen(str_array)*sizeof(char));
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    What I'm trying to do is, when the user enters their string (which could be arbitrary in length) I'm trying to get the malloc() function to take this information and dynamically allocate it. If I define an array, lets say array[100], I can allocate memory for the strings but it will have to be by way of strcpy(). I always presumed a pointer IS an array when dealing with chars.

  4. #4
    Registered User
    Join Date
    Jul 2014
    Posts
    50

    Code:
    #include
    Code:
    <stdio.h>
    #include
    <stdlib.h>
    #include
    <string.h>
    int
     main(void)
    {
        
    char *str_array;
        
    char array[100];
        
    printf("Enter a string:\n");
    
    scanf("%s", array);
    
        
    /* Request storage & point to block of allocated memory */
    
    str_array = (char*)malloc(strlen(array)*sizeof(char));
    
        
    /* Copy the contents of array[] to the dynamically allocated array */
    
    strcpy(str_array,array);
    
    printf("The string you entered was: %s", str_array);
    
        
    return 0;
        
    }
    
    

  5. #5
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    I can dynamically allocate a string like this, but I had to define an array to do it with a defined size.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    malloc() can be used with a size that is determined at either compile-time or runtime.

    Technically a VLA can also be used the same way
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Apr 2011
    Location
    dust
    Posts
    70
    Probably you can use
    Code:
    "%[^\n]%*c"
    or
    Code:
    "%[^\n]s"
    in scanf format specifier.
    This may help you, I am not sure.

  8. #8
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    Ok, I've proceeded on with entering six strings now. Can someone tell me if I've dynamically allocated 6 strings, and if this is right at all? I'm confused because I've had to make a strcpy() statement to do it for all six, so does that not mean I now have 6 dynamically allocated strings AND 6 arrays of size 100 in memory?

    This is why I was trying to avoid defining arrays, I'm now using memory I don't need to.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
     
    char *str_array[6];
        
    char array_i[100];
        
    
    int i, j;
    
    
    printf("Enter 6 strings:\n");
    
     
    for(i=0;i<6;i++)    
    {
    
            
    scanf("%s", array_i);
    
    
    str_array[i]= (char*)malloc(strlen(array_i)*sizeof(char));
    
     
    strcpy(str_array[i],array_i);
    
            
    }
    
    
    printf("Your strings were:");
    
     
    for(j=0;j<6;j++)
        {
    
            printf("%s\n", str_array[j]);
     
        }
     
        
    return 0;
        
    }
    
    


  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tripswitch
    Can someone tell me if I've dynamically allocated 6 strings, and if this is right at all?
    It looks close to correct. I suggest amending to:

    Code:
    #define NUM_STRINGS 6
    
    int main(void)
    {
        char *str_array[NUM_STRINGS];
    
        /* ... */
    
        for (i = 0; i < NUM_STRINGS; i++)
        {
            if (scanf("%99s", array_i) == 1)
            {
                str_array[i] = malloc(strlen(array_i) + 1);
                if (str_array[i])
                {
                    strcpy(str_array[i], array_i);
                }
                else
                {
                    /* Handle memory allocation failure */
                }
            }
            else
            {
                /* Handle invalid input */
            }
        }
    
        /* ... */
    I used a named constant instead of 6: avoid magic numbers. I used "%99s" instead of "%s" for the format specification to avoid buffer overflow since array_i is an array of 100 characters. Admittedly, this does involve a magic number, so later you may wish to improve it.

    For the malloc call, I removed the cast as it is unnecessary. I also removed the multiplication by sizeof(char) as sizeof(char) will always be equal to 1. If you prefer, you could write:
    Code:
    str_array[i] = malloc((strlen(array_i) + 1) * sizeof(str_array[i][0]));
    Note the + 1: you should account for the null terminator.

    Quote Originally Posted by Tripswitch
    I'm confused because I've had to make a strcpy() statement to do it for all six, so does that not mean I now have 6 dynamically allocated strings AND 6 arrays of size 100 in memory?
    Look at what you declared:
    Code:
    char *str_array[6];
        
    char array_i[100];
    This means that you have two arrays: one is an array of 6 pointers to char; the other is an array of 100 char. Later in your code, you use malloc to dynamically allocate storage for 6 arrays of char. Therefore, you end up with 2 arrays of fixed size and 6 dynamic arrays.

    I see that you forgot to free what you malloc'ed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    Ok I understand everything fine up until your last note. I know I've done this, but I couldn't think of any other way to use malloc() when entering the strings. It just crashes otherwise.

    Referring back to our first discussion, you mentioned you need the boxes to put your apples in, the char array_i[100] was those boxes. Then I used the strcpy() function to dynamically allocate these strings. The number 100 was arbitrary, I come across it quite frequently in texts for char arrays.

    I want to eliminate the char array_i[100] out of my code, and just dynamically allocate them straight away without having to do a strcpy() function.

  11. #11
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    Ohhh, you've done it! Sorry forget what I said about the array[100]. How do I get rid of strcpy()?
    Last edited by Tripswitch; 07-16-2014 at 12:09 PM.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tripswitch
    Referring back to our first discussion, you mentioned you need the boxes to put your apples in, the char array_i[100] was those boxes. Then I used the strcpy() function to dynamically allocate these strings. The number 100 was arbitrary, I come across it quite frequently in texts for char arrays.
    Aye, so by analogy, you got yourself a big box at home. You put the apples in the box, counted them, then went to the store to get a box that was just the right size and transferred them over. (Of course, the analogy fails in that you copied the characters over so they are in both arrays, but presumably you are not a wizard with the power to conjure up an identical set of apples.)

    Quote Originally Posted by Tripswitch
    I want to eliminate the char array_i[100] out of my code, and just dynamically allocate them straight away without having to do a strcpy() function.
    You can dynamically allocate an array of 100 characters, read into that array, then realloc to the desired size (or not).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    So if I reallocate instead of copying I'll be left with two arrays alone, not 3?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tripswitch
    So if I reallocate instead of copying I'll be left with two arrays alone, not 3?
    Three arrays? How are you counting three arrays?

    If you reallocate instead of copying, you'll be left with exactly one array per string, plus the fixed size array of pointers.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Jul 2014
    Posts
    50
    Sorry, I keep forgetting the six strings form 6 arrays.

    Is there a function to reallocate or do I have to make one?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Malloc strings?
    By Mentallic in forum C Programming
    Replies: 16
    Last Post: 10-07-2013, 01:00 PM
  2. how to use malloc for array of strings
    By SoFarAway in forum C Programming
    Replies: 3
    Last Post: 02-18-2005, 04:19 PM
  3. malloc() strings VS array strings
    By Kleid-0 in forum C Programming
    Replies: 5
    Last Post: 01-10-2005, 10:26 PM
  4. strings making sure user has entered some info
    By marcus430 in forum C++ Programming
    Replies: 3
    Last Post: 11-22-2003, 07:58 AM
  5. malloc with arrays of strings
    By Lib in forum C Programming
    Replies: 2
    Last Post: 08-03-2003, 10:46 PM