0

I'm still very new to C and get multiple error messages in my code and it would be nice if someone could explain these error messages to me.

My code:

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

int main()
{
  char newINPUT;

  char* INPUT = (char*)malloc(1 * sizeof(char));



  while((INPUT = getchar()) =! EOF)
    char* newINPUT = (char*)realloc(INPUT, 2* sizeof(INPUT));
    if(newINPUT =! NULL)
    {
      INPUT = newINPUT;
    }
    else
    {
      free(INPUT);
      printf("Out of memory!");
    }

    return 0;

}

What this shall do is: It should allocate some memory and read what you type. When there is no allocated memory left it should reallocate double as much memory as has been alocated before.

Error messages: warning line 13(that line with while): assignement makes pointer from integer without cast (enabled as default) error line13: lvalue required as left operand of assignement error line14: expected expression before 'char' warning line 17: same as line 13.

Would be nice if someone could explain that to me. Thanks!


EDIT: Thanks for all the answers so far! They truly helped me in understanding malloc und realloc. I've tried another own version yesterday, but I'm not sure if the allocated memory works right since I can't test it with an input large enough. Would that work (syntaxwise) with the realloc and the doubling?

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

int main()
{

  int *READ; //input
  READ = malloc(sizeof(int));


  while ((*READ = getchar()) != EOF)
  {
    if (READ) //if read not null so memory is enough
    {
      putchar(*READ);
    }
    else
    {
      int x;
      int* extendedREAD = realloc(READ, (x*2));//expression for "double as much as before"????

      if (extendedREAD = NULL) // looking if there s enough memory
      {
        printf("Error, not enough memory!");
      }
      x = x * 2;
    }
  }



  return 0;
}




/*
Zeichen einlesen - checken ob eof, wenn nein, dann speicher ausreichend? nein dann vergräßern, sonst zeichen dazuschreiben, dann wieder vonvorne)
*/

Thank you!

Yíu
  • 383
  • 3
  • 14
  • 1) `char newINPUT;` : This variable is not used. And duplicate names. – BLUEPIXY Nov 17 '14 at 11:42
  • 2) `INPUT = getchar()` : type of `INPUT` is `char *` . type of return value of `getchar()` is `int`. – BLUEPIXY Nov 17 '14 at 11:44
  • 3) `2* sizeof(INPUT)` : `sizeof(INPUT)` is `sizeof(char*)`. it's always same value. – BLUEPIXY Nov 17 '14 at 11:45
  • 4) `=!` should be `!=` – BLUEPIXY Nov 17 '14 at 11:45
  • 5) `while((INPUT = getchar()) =! EOF)` need `{ }` – BLUEPIXY Nov 17 '14 at 11:46
  • 6) `printf("Out of memory!");` : It is not possible to continue the loop. – BLUEPIXY Nov 17 '14 at 11:48
  • 7) `INPUT` has not been released prior to successful completion. – BLUEPIXY Nov 17 '14 at 11:50
  • 8) The input character is not added to the buffer. – BLUEPIXY Nov 17 '14 at 11:51
  • 9) Immediately allocation can no longer After extending the size doubled every time the character input. – BLUEPIXY Nov 17 '14 at 11:58
  • @BLUEPIXY :Thanks for the detailled answer! I'd still have some questions on this: 2.) When someone types in an input that will most likely be a character, rather than an integer number, but since getchar requires int I'm not sure what to chose. – Yíu Nov 18 '14 at 00:22
  • 3.) How is it then possible to do something like "Get inputs, if allocated mem is not enough, then double the allocated mem" - how would be the syntax for this? – Yíu Nov 18 '14 at 00:23
  • 5.) Why does a while statement neet {}? The block follows after I declared what must be the case for the block to start, or am I getting this wrong? – Yíu Nov 18 '14 at 00:24
  • The other errors are rather clear. Thanks so far! – Yíu Nov 18 '14 at 00:25
  • 3)getchar must return a value(EOF) other than a character in order to return a value indicating that the string could not be input. – BLUEPIXY Nov 18 '14 at 08:51
  • 5)`while(..)` , `char*..;`, `if...else...` : realloc-statement and if-statement will need to be run on the same block because it is associated. But if there is no `{ }` , Included in while only the first sentence(realloc-statement). – BLUEPIXY Nov 18 '14 at 08:56

2 Answers2

3

Lots of issues here...

int main()
{
  char newINPUT;

  char* INPUT = (char*)malloc(1 * sizeof(char));

Don't cast the result of a call to malloc(); it's unnecessary and can cause unexpected problems.

  while((INPUT = getchar()) =! EOF)

Two problems here. First, a =! b means "set a to the logical complement of b". You probably wanted to use something of the form a != b ("a not equal to b"). Second, getchar() returns an int value. If you try to store the return value in a char container, you may find that it will never be equal to EOF.

    char* newINPUT = (char*)realloc(INPUT, 2* sizeof(INPUT));

Here you are redeclaring newINPUT as a char* pointer. You declared it as char newINPUT earlier on. This will cause a compilation error.

    if(newINPUT =! NULL)

You are setting newINPUT to the logical complement of NULL here. I think you meant if (newINPUT != NULL). You could have simply used if (newINPUT) instead.

(Nonsense about memory leak deleted — my mistake!)

Overall, your program logic is flawed because you are attempting to double the allocated memory for every single character of input. So even if you fixed the above problems, you would run out of memory after inputting about 32 characters.


Suggested rewrite:

The following code stores the current size of the input buffer in size, and the length of the input string in nchars. Both are initialised to zero. The buffer location itself (char *input) can be initialised to NULL, because a call to realloc() with a null pointer is equivalent to calling malloc(). That means we can eliminate one system call from the code.

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

int main() {
  char *input=NULL, *new_input;
  int c, size=0, nchars=0;

  while (1) {
    if (size==nchars) {
      size = size*2 + (size==0);  /* (size==0) is 1 if size==0, zero othewise */
      if (!(new_input = realloc(input,size))) {
        puts("Out of memory");
        free(input);
        return 1;
      }
      input = new_input;
      printf("Buffer reallocated; new size is %d byte(s)\n",size);
    }
    if ((c=getchar())==EOF) {
      input[nchars] = '\0';  /* Terminate the input string */
      break;
    }
    input[nchars++] = c;
  }

  printf("Buffer size:   %d\n"
         "String length: %d\n"
         "Input was:     %s\n",size,nchars,input);
  free(input);
  return 0;
}
Community
  • 1
  • 1
r3mainer
  • 23,981
  • 3
  • 51
  • 88
  • Thanks for the long answer, really appreciate. Still I have some questions. Concerning the memory leak - why doesn't it have anything to point to anymore? I don't really get that part. – Yíu Nov 18 '14 at 00:27
  • And overall - I didn't want to double the allocated memory everytime a new character is added, I did want to double it only if the input has no available memory in the malloc, like it has doubled to from 8 to 16 it will only double after 9,10,11,12,13,14,15 - now. Do you have a tip how to write that down? – Yíu Nov 18 '14 at 00:29
  • If I'd write the while like " while((INPUT = getchar()) != EOF && INPUT != 0) it would only realloc more memory if it can't safe more into the input, meaning if no space is available anymore. Would that be right? – Yíu Nov 18 '14 at 00:34
  • @Yíu Sorry, I was wrong. There is no memory leak :-) If you want to double the memory allocation only when necessary, you will need to store the current size of the buffer and the number of characters it contains. I've added some code to show you how I would do it. – r3mainer Nov 18 '14 at 13:35
  • Thank you very much! I like the idea of eliminating one system call while not getting much more complicated. May i ask you to explain this line shortly? "if (!(new_input = realloc(input,size)))". I don't really understands what it does. – Yíu Nov 18 '14 at 18:02
  • I've also edited my question and posted a try I did before reading your answer, could you possibly have a short look on it? – Yíu Nov 18 '14 at 18:07
  • @Yíu `new_input = realloc(input,size)` sets `new_input` to the address of the new memory block if successful, or to NULL (i.e., 0) otherwise. `!x` is the logical inverse of `x`, which is `1` if `x` is zero, or `0` otherwise. Your edited code won't work. As I mentioned before, you need to store the current size of the buffer and the number of characters it contains. Your code does not store either of these things, and therefore cannot work properly. I think you need to read up on C pointers and how to use them. [Try searching Google.](google.com/search?q=C+pointers+and+how+to+use+them) – r3mainer Nov 18 '14 at 19:47
0

An example of a modification

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

int main(void){
    int ch;
    char* INPUT = (char*)malloc(1 * sizeof(char));
    int input_buf_size = 1;
    int input_count = 0;

    while((ch = getchar()) != EOF){
        INPUT[input_count] = ch;
        input_count += 1;
        if(input_count == input_buf_size){
            char *newINPUT = (char*)realloc(INPUT, input_buf_size *= 2);
            if(newINPUT != NULL){
                INPUT = newINPUT;
            } else {
                free(INPUT);
                printf("Out of memory!");
                exit(EXIT_FAILURE);
            }
        }
    }
    INPUT[input_count] = '\0';
    puts(INPUT);
    free(INPUT);
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • Your solution is really good and understandable. Nevertheless I don't really understand why you need INPUT[input_count] = ch; . Is this the same as if you would write the put(INPUT) in the while loop? I've never seen it written like this. – Yíu Nov 18 '14 at 17:51
  • I've also edited my question and posted a try I did before reading your answer, could you possibly have a short look on it? – Yíu Nov 18 '14 at 18:07
  • @Yíu `*READ = getchar()` : This is only use the beginning of the buffer. – BLUEPIXY Nov 18 '14 at 21:14
  • @Yíu Newly added your code has also included the problem. – BLUEPIXY Nov 18 '14 at 21:22