0

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!

6
  • 1
    sizeof(charSize) will give you the size of an int since harSize is an int. Instead, just do sizeof(char) Commented Dec 18, 2013 at 6:53
  • 3
    Even better, omit it completely, as sizeof(char) is by definition 1. Commented Dec 18, 2013 at 6:55
  • you may want to reconsider doing a realloc with an extra 2 bytes since it's not very effective, if your environment is not an embedded one (where every byte counts) simply add a block of say 100 bytes if space is not enough, it would reduce the number of reallocs. Have a variable the keep tracks of the buffer size, increase this when you realloc. Commented Dec 18, 2013 at 7:00
  • ptr is a buffer of ints, not chars. sizeof(charSize) may seem confused but it is (perhaps unintentionally) correct. Use sizeof *ptr instead, as that will always work, especially if you ever change the type of ptr. Commented Dec 18, 2013 at 7:09
  • @Kninnug, charSize is intetentional to initilize each cell to be 1 bit even though it's int. Maybe I should change the name of the variable? Thank you all for answering. Commented Dec 18, 2013 at 7:42

2 Answers 2

1

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 (i.e. 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-mallocing 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.

Sign up to request clarification or add additional context in comments.

Comments

0

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;
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.