Lap allocate a memory based on the size of what the user typed

How can I make it right after the user enters a String the program counts the 'x' number of characters from this and allocates X bytes to it?

I am not able to do it, I tried for example to make that after the user enters the string, this:

ponteiro = (char *) malloc (strlen(string));

In the above code, the user giving an input, for example, of the type: ABCDEF, would make the strlen count 6 characters, thus allocating to the string 6 bytes.

But it goes wrong, since memory allocation would be happening later, so before the string is 'picked up' there would be no bytes allocated to store it.
Does anyone know how I solve this?

Author: Maniero, 2015-01-04

3 answers

There are not many options. Basically either you allocate a sufficient amount first for what you need or ask how much you want to allocate.

The second option really is terrible. From the point of view of usability it does not make the slightest sense.

The first option has the disadvantage of possibly allocating more memory than is actually needed. But who cares. This is not a problem anymore on any type of device unless you want to enter with text really a lot long, but you wouldn't do this simply anyway, in a long text you would have a data structure to manage this.

One might think that there is also the downside of imposing a cap. But this is an advantage. Leaving a user what is the maximum limit of text to type is the last thing the program should do. Again, if you need something more complex, you need a more complex program.

So the solution is to do this:

#include <stdio.h>
#include <stdlib.h>
int main(){
    char *ponteiro = malloc(100); //um caractere será ocupado pelo terminador \0
    printf("String: ");
    scanf("%99s", ponteiro); //permite digitar um caractere a menos que o alocado 
    free(ponteiro);
    return 0;
}

See not working ideone. E no repl.it. also I put on GitHub for future reference .

Now answers have appeared that show creative algorithms but that will probably be overkill . My solution wastes memory, the others presented waste allocation time and in the comment appeared one that wastes or two but in moderate amounts.

Did you notice that there is no free lunch? You you have to decide what you want to waste. In a simple example any can be wasted without problems. I would use the Occam knife and I would take the simplest one. If I preferred the more complicated one I would have posted it.

I could use an optimized and better handled version on more complex issues where I was actually having memory issues and didn't know the size of what I need in data input. I don't have any of these problems ever then I never worried about that. I don't think you should either.

 4
Author: Maniero, 2020-09-16 15:43:21

There is a way to do what you want, but Code performance is questionable depending on the situation.

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

#define ALLOCATION_STEP 5

int main(void)
{
    int mem_left = ALLOCATION_STEP;
    int mem_size = mem_left + 1;
    int length = 0;
    int realloc_cnt = 0;
    char *buff = (char *)malloc(mem_left);
    char c = 0;
    while((c = getchar()) != '\n') {
        if(mem_left == 0) { // precisamos de mais memoria
            char *tmp = (char *)realloc(buff,mem_size + ALLOCATION_STEP);
            if(tmp == NULL) {
                printf("Falha na aquisicao de memoria!\n");
                free(buff);
                return -1;
            }
            buff = tmp;
            mem_left = ALLOCATION_STEP;
            mem_size += mem_left;
            ++realloc_cnt;
        }
        buff[length++] = c;
        --mem_left;
    }

    buff[length] = '\0'; // fecha a string

    printf("Tamanho: %d\n",length);
    printf("Memoria: %d\n",mem_size);
    printf("Padding: %d\n",mem_size - (length+1));
    printf("Realocacoes: %d\n",realloc_cnt);
    printf("String: %s\n",buff);

    free(buff);
    buff = NULL;

    return 0;
}

The above code allocates an initial amount of memory given by the value of ALLOCATION_STEP, then it starts reading the input stream until it finds a line break \n, throughout the process it will copy the characters of the stream to the variable buff, if the amount of remaining memory indicated by mem_left reaches 0 it relocates more ALLOCATION_STEP bytes of memory to continue the process to the end or until an allocation error occurs.

The problem is: a too low ALLOCATION_STEP can cause many relocations to happen making code performance questionable, there is also the abusive use of the realloc function that can bring problems.

 3
Author: Cahe, 2015-01-04 18:16:16

Simple

: in the same way that C++ does with std::string. Leave the input buffer, read from chunk to chunk and allocate more memory as needed.

Uses the following Code :

char *getln()
{
    char *linha = NULL, *tmp = NULL;
    size_t tamanho = 0, index = 0;
    int ch = EOF;

    while (ch) {
        ch = getc(stdin);

        /* Checamos se devemos parar. */
        if (ch == EOF || ch == '\n')
            ch = 0;

        /* Checamos se devemos expandir. */
        if (tamanho <= index) {
            tamanho += CHUNK;
            tmp = realloc(linha, tamanho);
            if (!tmp) {
                free(linha);
                linha = NULL;
                break;
            }
             linha = tmp;
        }

        /* Finalmente adicionamos o caractere */
        linha[index++] = ch;
    }

    return linha;
}

Remembering that CHUNK is a value fit for you. The flawless way is #define CHUNK 1. The method can change the time results ( input much longer ).

 2
Author: Comunidade, 2017-05-23 12:37:29