Thread: Malloc function and program crash

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    19

    Malloc function and program crash

    I try to learn malloc function and I have some problems. This program compiles nicely but it crashes after I have entered one line text and pressed enter. Array is the array where I try to allocate all the text from input string.
    On this context array = (char*) malloc(sizeof(char)*10); means that I have made an array named array with 10 cells: array[0], ..., array[9].
    What's wrong and how to make it work?


    Code:
    int main(int argc, char* argv[])
    {
    char * input;
    char * array;
    input = (char*) malloc(sizeof(char)*1);
    array = (char*) malloc(sizeof(char)*10);
    int i=0;
    
    printf("Please input some text\n");
    while(*input!='0')
    {
          gets(input);
          *(array+i)=*input;
          if(*input!='0')
                 printf("You inserted, %d: %s\n",i+1, *(array+i));
          i++;
    }
    
    return 0;
    }

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    1) Never, ever use gets. http://cpwiki.sourceforge.net/Gets
    Gets also reads a string, not a character, so you will get a buffer overrun.
    2) *(array + 1) can simply be written as array[1]. Much better.
    3) Always free what you malloc.
    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.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    among other things, you allocate only 1 byte for 'input' while gets() read a string (terminated by \0), you probably meant to read only one character.

    EDIT: for the others things, see the post above

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >(char*) malloc
    You don't need to cast the result of malloc in C. In fact, doing so will hide legitimate errors that are somewhat serious.

    >input = (char*) malloc(sizeof(char)*1);
    >array = (char*) malloc(sizeof(char)*10);
    >int i=0;
    Mixing statements and declarations is a new feature to C, so unless you're using a compiler that supports C99 and is set to C99 mode, I'd wager that you're accidentally compiling as C++.

    >while(*input!='0')
    What about when you reach the limit of array? You only allocate 10 characters, which with a null character only gives you 9. I don't see anywhere where you handle buffer overflows.

    >gets(input);
    That's pretty much a guaranteed buffer overflow unless you only enter blank lines. You should actually be using a single character and getchar rather than gets here.

    >printf("You inserted, %d: %s\n",i+1, *(array+i));
    The error you're getting is probably coming from here. You try to print array[i] as a string, but it's not a string, and you can't predict where the next null character will be. Use %c instead.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    My goal is to implement a program which allocates some space to array and then reads user input and puts it into array. If it runs out of memory it reallocates the memory by certain amount and copies old data into new memory location. That's why I am tring to use malloc function.

  6. #6
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by totalnewbie View Post
    My goal is to implement a program which allocates some space to array and then reads user input and puts it into array. If it runs out of memory it reallocates the memory by certain amount and copies old data into new memory location. That's why I am tring to use malloc function.
    Fascinating, sport. For such an approach wouldn't getchar() be more advantageous?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by totalnewbie View Post
    My goal is to implement a program which allocates some space to array and then reads user input and puts it into array. If it runs out of memory it reallocates the memory by certain amount and copies old data into new memory location. That's why I am tring to use malloc function.
    Nothing wrong with that, but you should familiarize yourself with malloc and strings and characters, and dynamic memory handling in general first.
    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.

  8. #8
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Buffering input is tricky business, when it comes to doing it from the keyboard. I mean I have written handlers that read from sockets that delimit by line (similarly to fgets()) but you get entire chunks of data all at once. The user doesn't type arbitarily long blocks of data to buffer in that way. I hope that made sense to you. I know that was the worst wording ever.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >If it runs out of memory it reallocates the memory by certain amount and copies old data into new memory location.
    Then you should keep track of the current number of characters and the capacity of your memory block. When the number of characters matches the capacity, bump it up:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main ( void )
    {
      char *s = NULL;
      size_t size = 0;
      size_t capacity = 0;
      int ch;
    
      while ( ( ch = getchar() ) != '\n' && ch != EOF ) {
        if ( size == capacity ) {
          char *save;
    
          capacity += 5; /* Arbitrary amount */
    
          /* +1 for the null character */
          save = realloc ( s, capacity + 1 );
    
          if ( save == NULL )
            break;
    
          s = save;
        }
    
        s[size++] = ch;
      }
    
      if ( size > 0 ) {
        s[size] = '\0';
        puts ( s );
      }
    
      free ( s );
    
      return 0;
    }
    My best code is written with the delete key.

  10. #10
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Read up on realloc if you need to restructure your previously allocated block of memory by malloc.

  11. #11
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    You may want to think how efficient this will be within your program using realloc though.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    Quote Originally Posted by Prelude View Post
    >If it runs out of memory it reallocates the memory by certain amount and copies old data into new memory location.
    Then you should keep track of the current number of characters and the capacity of your memory block. When the number of characters matches the capacity, bump it up:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main ( void )
    {
      char *s = NULL;
      size_t size = 0;
      size_t capacity = 0;
      int ch;
    
      while ( ( ch = getchar() ) != '\n' && ch != EOF ) {
        if ( size == capacity ) {
          char *save;
    
          capacity += 5; /* Arbitrary amount */
    
          /* +1 for the null character */
          save = realloc ( s, capacity + 1 );
    
          if ( save == NULL )
            break;
    
          s = save;
        }
    
        s[size++] = ch;
      }
    
      if ( size > 0 ) {
        s[size] = '\0';
        puts ( s );
      }
    
      free ( s );
    
      return 0;
    }
    What if I want to put these characters into multidimensional array?
    Scrutinizing your code I cannot see where memory space checking takes place. The size of the memory is increased by 5 units
    Code:
    capacity += 5; /* Arbitrary amount */
    There is no direct place where it is pointed out for instance checking the size of input and array.
    The following is the most likely place where it could occur but there is no counter which increases the size of size variable or else variable.
    Code:
    if ( size == capacity ) {
    You haven't used malloc function, you implement this program just using realloc function and I'm wondering how you can succeed without using firstly malloc function.

    Code:
    if ( size > 0 ) {
        s[size] = '\0';
        puts ( s );
      }
    It appears to me that after the function has finished its job it writes '\0' at the last place of the array.

  13. #13
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by totalnewbie View Post
    1. What if I want to put these characters into multidimensional array?
    2. Scrutinizing your code I cannot see where memory space checking takes place. The size of the memory is increased by 5 units
    Code:
    capacity += 5; /* Arbitrary amount */
    There is no direct place where it is pointed out for instance checking the size of input and array.
    3.
    The following is the most likely place where it could occur but there is no counter which increases the size of size variable or else variable.
    Code:
    if ( size == capacity ) {
    4. You haven't used malloc function, you implement this program just using realloc function and I'm wondering how you can succeed without using firstly malloc function.

    Code:
    if ( size > 0 ) {
        s[size] = '\0';
        puts ( s );
      }
    5. It appears to me that after the function has finished its job it writes '\0' at the last place of the array.
    1. What about it? You just change the single set of [] to a double set with valid indices.
    2. Space checking takes place in the (if size == capacity) line.
    3. It's not the size variable that's increased, but rather the capacity.
    4. Have you read up on realloc at all?
    5. Have you come across strings before? And how they have to be NULL terminated?

    QuantumPete
    "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

  14. #14
    Registered User
    Join Date
    Nov 2008
    Posts
    19
    Quote Originally Posted by QuantumPete View Post
    1. What about it? You just change the single set of [] to a double set with valid indices.
    2. Space checking takes place in the (if size == capacity) line.
    3. It's not the size variable that's increased, but rather the capacity.
    4. Have you read up on realloc at all?
    5. Have you come across strings before? And how they have to be NULL terminated?

    QuantumPete
    4. I've been checking examples which at first use malloc and then realloc. That's why I used to think that it's not possible to use malloc and realloc separately.
    5. I usually program in Java, there's no problems with memory allocation or strings but in C they are entirely different. That's why I was so confused at first.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by totalnewbie
    I've been checking examples which at first use malloc and then realloc. That's why I used to think that it's not possible to use malloc and realloc separately.
    It is possible to use realloc() without using malloc(). Depending on how you use it, realloc() could do the same thing as malloc().
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM