0

I'm quite new to dynamic memory allocation in general. I've been looking for an error in this code for about 6 hours in the last 3 days now, it's driving me crazy, that's why I've decided to ask for help here. Here's the code:

char ch;
char* line=(char*)calloc(1, sizeof(char));

if(input!=NULL) {
    for(int num=1; (ch=fgetc(input)) != EOF; num++) //input is the pointer to the in file
        if(ch!=' ') {
            line=(char*)realloc(line, sizeof(char)*num+1);
            strcat(line, &ch);
        }
        else
            break;
}

I'm trying to read from a file the first of two whitespace-separated words, where the total size is not predetermined (I'll need this to read even more from the file so it's important, this was "just to try"). This is for a single line, not multiple lines (char** I think would be used in that case), and the idea was to allocate the first character of the line and set it to zero, then reallocate the memory incrementing its size by one character. If I "num++", it crashes; if I don't, its output will be, instead of "Nole", this: N☺o☺l☺e☺ (output is after the loop; how does it even increase if num remains the same?). I checked the ASCII codes and this is what I get: 78 1 111 1 108 1 101 1; there is a '1' after every character, which is THE SAME value as "num" (in fact, if num==2, then I get '2's instead of '1's). I've tried it with different compilers and different machines but I always get the same result and I cannot explain why. I'm really going crazy, also because I'm gonna have an exam in about two weeks and this is basically the only thing I haven't learned yet among all the required topics.

Thank you so much in advance 😿

5
  • 1
    strcat ecpects two NUL terminated strings but you pass a pointer to a single character where there's no guarantee that there is '\0' at the next memory address, so that invokes UB. You could replace strcat by line[num-1] = ch; line[num] = '\0'; Commented Jun 17, 2022 at 9:44
  • Also ch can never become EOF since it wasn't declared int. As it happens, declaring it int on a little endian machine will sneakily hide away the bug (don't try this at home) because now strcat thinks that the more significant bytes of the int is the null terminator. Useful for code golfing... :) Commented Jun 17, 2022 at 9:46
  • Thank you so much!!! Instead of "ch" I'm now using "ch[2]" and set ch[1]='\0'. The char that'll be used will be "ch[0]". Commented Jun 17, 2022 at 9:56
  • using char ch[2] still doesn't solve the problem with EOF being an int Commented Jun 17, 2022 at 10:11
  • Right... I'll manage to fix it later, the biggest problem for me was with strcat Commented Jun 17, 2022 at 10:16

1 Answer 1

1
  • EOF is an int so you must use int ch;

  • As mentioned in comments, you pass a single ch to strcat and not a null terminated string, so it will go haywire. Quick fix: strcat(line, (char[2]){ch,'\0'});.

    Or if you add a counter, you could just do line[count] = ch; which is much more efficient. Though in that case you'll have to remember to append the null terminator manually in the end.

Also, sizeof(char) is always 1 by the very definition of sizeof, so it's just a needlessly bloated way of writing 1.

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

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.