简体   繁体   中英

Dynamic memory allocation with int array

I have an assignment in which I have to accept an input from the user. I can't use a linked list, only an array, so my plan is:

  1. Alloc some memory.

  2. If we need to realloc, meaning that I reached the number of cells allocated:

    1. Try to realloc. If successful, great.

    2. If we couldn't realloc, print input, free memory and realloc then.

I can't really decide about the command that tells me how did I reach the end of memory allocated and that's why I need your help. I wrote:

if (i==(MAX_CHARS_INPUT-1))

But I am not sure about it.

The code:

#include <stdio.h>
#include <stdlib.h>

#define MAX_CHARS_INPUT 200
#define D_SIZE 2

void printWithMalloc(){
    int charSize=1; 
    int *ptr=malloc(MAX_CHARS_INPUT*sizeof(charSize));

    int i=0, j=0, c;
    printf("please enter a string\n");

    while ((c=getchar())!=EOF && c!='\n')
    {
        ptr[i++]=c;
        if (i==(MAX_CHARS_INPUT-1)) /*if we need to realloc*/
        {
            int *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(charSize));
            if (temp==NULL) /*realloc failed*/
            {
                printf("you wrote:\n");
                while(j<=i)
                    putchar(ptr[j++]);

                free(ptr);
                ptr=(int*)malloc(MAX_CHARS_INPUT*sizeof(charSize));
            }
            else
                ptr=temp;
        }
    }
}

int main(){
    printWithMalloc();
    return 0;
}

Thank you!

The problem is indeed with your condition:

if (i==(MAX_CHARS_INPUT-1))

This works, but only for the first time you reach this limit. When you realloc your buffer gets bigger, but you don't check if you run out of that space. So imagine I input 500 characters. When the 199th character is read the buffer is reallocated to become 400 characters big. However, i is only checked at the 199th character, so when the 400th one is reached it will run out of the buffer.

The second problem is that when you reallocate the buffer it will only grow to 400 characters ( D_SIZE * MAX_CHARS_INPUT ) and no bigger.

The third problem is when you re- malloc (ie when realloc failed) you don't reset i so it will write past the end of the buffer immediately.

As suggested in a now deleted answer. Keep track of your buffer-size:

size_t buffSize = MAX_CHARS_INPUT;

when you reallocate, update buffSize first, then use that as the argument to realloc :

buffSize *= D_SIZE; // double the buffer-size
temp = realloc(ptr, buffSize * sizeof(*temp)); // using sizeof *temp is less confusing and less error-prone

of course: also update your condition:

if(i == buffSize - 1)

and when you re- malloc reset i and buffSize :

buffSize = MAX_CHARS_INPUT;
ptr = malloc(buffSize*sizeof(*ptr));
i = 0;

Though re- malloc ing is not very wise, since if an allocation fails there are usually bigger problems (unless memory is very restricted). And (especially since you don't check the result of that malloc ) possibly problematic since that malloc may fail as well. Exiting a program after an alloc-fail is not unusual.

There are few things getting wrong in your code, the new code is:

  #include <stdio.h>
  #include <stdlib.h>

  #define MAX_CHARS_INPUT 200
  #define D_SIZE 2

  void printWithMalloc(){
      //int charSize=1; you don't need this.
      //int *ptr=malloc(MAX_CHARS_INPUT*sizeof(charSize));
      char *ptr=malloc(MAX_CHARS_INPUT*sizeof(char));//sizeof(char) will give you the block size, MAX_CHARS_INPUT: gives you the number of blocks to be allocated and pointer type is char, since you want to save char(s), right?

      int i=0, j=0, c;
      printf("please enter a string\n");

      //while ((c=getchar())!=EOF && c!='\n')
       while ((c=getchar())!='\r') //'\r' is for enter key... since the user input is coming from console not form a file, right?
      {
          ptr[i++]=c;
          if (i==(MAX_CHARS_INPUT-1)) /*if we need to realloc*/
          if (i==MAX_CHARS_INPUT) // i is already incremented in i++
          {
              //int *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(charSize));
              char *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(char));
              if (temp==NULL) /*realloc failed*/
              {
                  printf("you wrote:\n");
                  while(j<=i)
                      putchar(ptr[j++]);

                  free(ptr);
                  ptr=(char*)malloc(MAX_CHARS_INPUT*sizeof(char));
              }
              else
                  ptr=temp;
          }
      }
  }

  int main(){
      printWithMalloc();
      return 0;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM