Thread: Dynamic Memory Allocation

  1. #1
    Registered User slash.hack's Avatar
    Join Date
    Sep 2011
    Posts
    21

    Dynamic Memory Allocation

    Trying to write a program that allocates memory as the user enters the number of characters, it doesn't work, where did it go wrong and why? Happy to be corrected.

    Code:
    #include<stdio.h>
    #include<conio.h>
    int main()
    
    {
        char *c; int n = 0;
        printf("Enter a string:\n");
    
    
        while((c[n]=getche())!=0x0D)
        {
            c[n+1]=(char *)malloc(sizeof(char));
            n++;
    
        }
        
        printf("%s",c);
        return 0;
    }
    And yeah, any replacement for getch()?

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    malloc() returns a pointer to the chunk of memory allocated; is c[n+1] of type pointer to char?

  3. #3
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    That whole thing is broke. Initially c is an unitialized pointer that you then try to store a value into; hence you are into undefined behavior. A malloc call only sizes an array once, using looping like this you would need an initial malloc call followed by realloc calls.

    getch() is part of conio.h and is nonstandard. Just use getchar() here which is defined in the stdio header. If you are trying to make your own equivalent of getline here, you would want to look at a recursive solution; which for this case is much simpler to implement.

    EDIT: Don't cast malloc. Casting Malloc-FAQ()
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Also... you want to remember to null terminate the character array prior to printing it out.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #5
    Registered User slash.hack's Avatar
    Join Date
    Sep 2011
    Posts
    21
    Updated :
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h>
    int main()
    
    {
        char *c, temp; int n = 0;
        c =  malloc(sizeof(char));
    
        printf("Enter a string:\n");
        while((temp=getche())!='\r')
        {
            *c[n]=temp;
            c[n+1]= malloc(sizeof(int));
            n++;
        }
    
        printf("%s",c);
        return 0;
    }
    getchar() wont work because the program is supposed to read and store as the user inputs the key.

    Having an error on line 13: D:\Workspace\bitstr.c|13|error: invalid type argument of 'unary *' (have 'int')

    Uncasting causes this to appear, as for line 14: D:\Workspace\bitstr.c|14|warning: assignment makes integer from pointer without a cast|. (I read the link, please clarify)

    EDIT: hk_mp5kpdw, will fix that after I get the code to run at least.

    Thank you all for helping.
    Last edited by slash.hack; 09-29-2011 at 10:34 AM.

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    c =  malloc(sizeof(char));
    sizeof(char) is guaranteed to always be 1 (I believe)... so you could just say malloc(1) if you wanted. This allocates a single character from the heap and assigns the address to c. The only index that is valid from an array indexing scheme at this stage in the game is 0, for example c[0], anything else is invalid. Remember that for later.


    Code:
    char *c, temp; int n = 0;
    ...
    while((temp=getche())!='\r')
    getche returns an int not a char, this can be important in cases where you may expect to have EOF returned and need to process it.


    Code:
    *c[n]=temp;
    The * part here makes no sense, c[n] by itself is perfectly fine. That's the cause of the error you mention in your post above.


    Code:
    c[n+1]= malloc(sizeof(int));
    Remember what I said about c[0] being the only valid index (the first time through the loop)? Here you attempt to access c[1] which is an invalid access (trying to access memory you have not be given permission to access) and assign it an address off the heap. Also, c[1] a char and not a char* type so the assignment doesn't make sense from that perspective. Third, you are using malloc where I'm thinking you probably want to be using realloc within the loop. Fourth, sizeof(int)? The first time through the loop your allocated memory size is 1, you want to allocate 1 more byte than the previous iteration's size to increase the size.


    How about a call to delete towards the end of your code just for grins?
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User slash.hack's Avatar
    Join Date
    Sep 2011
    Posts
    21
    Well, yes using malloc(1) would do the job, but still I used malloc(sizeof(char)) just to be sure.

    About getche, it does return an int, but int can be used in char because of ASCII, but please clear out this, int takes up 4 bytes where as a character 1 byte, and as this is for string, would typecasting "(char)getche() " do the job?

    c[n] is supposed to be pointing an address, therefore wouldn't "*c[n]" mean value at address in c[n]?
    And about c[1] and others being invalid besides c[0], I tested it.
    ...And figured out that malloc wasn't necessary (verify please).

    Code:
    #include<stdio.h>
    int main()
    {
        char *c;
        c[0] = 'x';
        c[1] = 'y';
            printf("\n%c\n%c", c[0],c[1]);
    }
    I'm not much good at pointers and such stuff, so its kinda difficult for me to put my queries and thoughts here.
    I'd really appreciate some more help because understanding this would mean a really great to me. Thank you.

    Updated the code again, it ran after fixing some stuff up.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h>
    char main()
    
    {
        char *c, temp; int n = 0;
        c = malloc(1);
        printf("Enter a string:\n");
        while((temp=(char)getche())!='\r')
        {
         c[n] = temp;
         n++;
        }
        c[n]= '\0';
        printf("\n%s",c);
        return 0;
    }
    What I did come across while editing the code was that using "int *c, temp;" caused only the first character to show up while echoing the resulting string, obviously due to the difference in memory allocation that int and char took. Plus, I saw no difference in typecasting getche().


    And, yeah, offtopic, manually adding [CODE] tags caused the code to appear only in plain text, why <-- I take that back
    Last edited by slash.hack; 09-30-2011 at 04:17 AM.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You can't have one char's size of an array, and then keep adding more data to it.

    May I suggest you malloc() a decent size to c[] first, and then keep a counter of how many char's you enter. When your counter reaches size of c[] - 1, realloc() your array, to a larger size (a substantially larger size, not just a few chars).

    Continually malloc()'ing and realloc()'ing memory, in small sizes, can eventually leave your memory available in shredded disarray, rather like Swiss cheese. Take your memory in sizeable blocks (BUFSIZ or more, is better than repeated allocations smaller than BUFSIZ).

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by slash.hack View Post
    About getche, it does return an int, but int can be used in char because of ASCII, but please clear out this, int takes up 4 bytes where as a character 1 byte, and as this is for string, would typecasting "(char)getche() " do the job?
    You can't fit four bytes into one.
    Code:
    char c;
    
    c = getchar();
    However, that's not the correct way to do it, and there is a specific reason those functions return an int.
    Code:
    int c;
    char key;
    
    c = getchar();
    if( c != EOF )
        key = c;
    They return an int, because EOF is a negative integer that doesn't correspond to any char value. So if you squish EOF into a char, and you are trying to use that to read a file that has assorted bytes in it, you will get false positives.


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

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by slash.hack View Post
    Trying to write a program that allocates memory as the user enters the number of characters, it doesn't work, where did it go wrong and why? Happy to be corrected.

    Code:
    #include<stdio.h>
    #include<conio.h>
    int main()
    
    {
        char *c; int n = 0;
        printf("Enter a string:\n");
    
    
        while((c[n]=getche())!=0x0D)
        {
            c[n+1]=(char *)malloc(sizeof(char));
            n++;
    
        }
        
        printf("%s",c);
        return 0;
    }
    And yeah, any replacement for getch()?
    Usually the best way is to malloc() a reasonably sized buffer at the beginning... say 100 characters?
    Then feed his input into the array as he types or on some signal such as pressing enter... fgets() is good for this!
    When he approaches the limit of the buffer use realloc() to expand the buffer another 100 characters...
    Loop through entries getting text, tracking where it ends... get more space in blocks.

    Trying to do this character by character is going to be painfully slow...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamic memory allocation
    By silver_comet in forum C Programming
    Replies: 2
    Last Post: 05-30-2011, 12:05 PM
  2. what is dynamic memory allocation
    By dbzx in forum C Programming
    Replies: 7
    Last Post: 06-08-2009, 08:11 AM
  3. Help with dynamic memory allocation
    By malooch in forum C Programming
    Replies: 2
    Last Post: 12-13-2006, 01:26 PM
  4. dynamic memory allocation w/o new
    By bd43274 in forum C++ Programming
    Replies: 11
    Last Post: 02-15-2006, 02:12 AM
  5. dynamic memory allocation
    By mag_chan in forum C Programming
    Replies: 13
    Last Post: 10-21-2005, 07:54 AM