0

My question was answered in another previous old question here but it was answered with code only & no explanation link.
I would love an answer why the code there works & mine not (what I'm missing?), this is mine:

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

void get_sentence(char* sentence) {
    char end_of_input = 'a', * temp_pointer = NULL;
    for (unsigned short int input_index = 0; end_of_input != '\n'; input_index -= -1) {
        temp_pointer = sentence;
        sentence[input_index] = end_of_input = getchar();
        printf("%d: %c\n", (1 + input_index), end_of_input);
        if (end_of_input == '\n') {
            printf("end of input\n");
            sentence[input_index] = '\0';
            return;
        }
        sentence = (char*)realloc(sentence, ((int)(input_index + 2)) * sizeof(char));
        if (sentence == NULL) {
            free(temp_pointer);
            return;
        }
    }
}

void main(int argc, char const* argv[]) {
    char* sentence = malloc(sizeof(char));
    if (sentence == NULL) {
        printf("blyat");
        exit(1);
    }
    get_sentence(sentence);
    printf("Answer = ");
    for (unsigned short int run = 0; sentence[run] != '\0'; run -= -1)
        printf("%c", sentence[run]);
    printf("\n");
    free(sentence);
    exit(0);
}

In the answer code he also does +=16 which is a waste of memory isn't it?.

barakadax
  • 47
  • 9
  • 3
    Note that the `sentence` variable in the `get_sentence` function is local to that function and modifications to it will not be reflected in `main`. – 001 Dec 31 '20 at 20:01
  • Should I write it than with ```&```?. – barakadax Dec 31 '20 at 20:03
  • 1
    Changing a parameter inside a function (like `sentence`) does not change the corresponding variable outside the function, even if that parameter is a pointer (this is the bit that newbies seem to get confused about). – john Dec 31 '20 at 20:03
  • 2
    @barakadax To me the easier solution is to return the (possibly) new value of sentence from the function. – john Dec 31 '20 at 20:05
  • 1
    `+= 16` is a tradeoff between speed and memory. Yes, it wastes a little bit of memory, but it means you don't need to call relative-expensive `realloc` for every character you want to add to the string. Note there is a final `realloc` that relinquishess any extra, so there's no memory wasted after all. – ikegami Dec 31 '20 at 20:07
  • 1
    @barakadax Which now I look at the linked question is exactly what is being done there, so that's the explanation of why the linked code works and yours does not. – john Dec 31 '20 at 20:08
  • 2
    @ikegami Since all `malloc()` implementations must return memory ["suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement"](https://port70.net/~nsz/c/c11/n1570.html#7.22.3p1), in practice `+=16` doesn't waste much if any space because internally, heap memory is allocated in blocks. In Linux, I'm pretty sure that block size is 16, so in this case `+=16` might actually be optimal and the final `realloc()` to trim the memory actually useless. (Which is also why overrunning a `malloc()`'d buffer often has absolutely zero symptoms.) – Andrew Henle Dec 31 '20 at 20:22
  • 1
    And unless you're trying to reinvent [`getline()`/`getdelim()`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html) for educational purposes, just use `getline()` or `getdelim()`. – Andrew Henle Dec 31 '20 at 20:25
  • 1
    @Andrew Henle, yeah, I realized that. I thought it was more important to teach the concept that sometimes wasting a bit of memory isn't a bad thing. :) – ikegami Dec 31 '20 at 20:49

1 Answers1

0

IT IS WORKING THANK YOU "@Johnny Mopp" ♥.

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

char* get_sentence() {
    char end_of_input = 'a', *sentence = malloc(sizeof(char)), *temp_pointer = NULL;
    for (unsigned short int input_index = 0; end_of_input != '\n'; input_index -= -1) {
        temp_pointer = sentence;
        sentence[input_index] = end_of_input = getchar();
        if (end_of_input == '\n') {
            sentence[input_index] = '\0';
            return sentence;
        }
        sentence = (char*)realloc(sentence, ((int)(input_index + 2)) * sizeof(char));
        if (sentence == NULL) {
            free(temp_pointer);
            return NULL;
        }
    }
}

int main(int argc, char const* argv[]) {
    char* sentence = get_sentence(&sentence);
    if (!sentence)
        exit(1);
    printf("Answer: %s\n", sentence);
    free(sentence);
    exit(0);
}
barakadax
  • 47
  • 9
  • 1
    It should be `int main() {.` – Ed Heal Dec 31 '20 at 20:11
  • 1
    Aside: With goal of "C getting unknown input length", why use `unsigned short int input_index`. `size_t input_index` would work better with pathological long lines, yet by that time the constant reallocating for every character would be come quite noticeable. Consider doubling that allocation each time with maybe a final right-size allocation. – chux - Reinstate Monica Dec 31 '20 at 20:20
  • 1
    Note that `getchar()` typically returns 257 different values. This code lack `EOF` detection and would eventually incur out-of-memory or integer overflow issues on end-of-file from `stdin`. – chux - Reinstate Monica Dec 31 '20 at 20:23
  • 1
    barakadax I'd expect `get_sentence(&sentence)` to generate an error or warnings , as `get_sentence()` expects no arguments. If not, enable all warnings. – chux - Reinstate Monica Dec 31 '20 at 20:26