Segmentation Fault

0

I would like to allocate memory dynamically without informing how many elements a vector would have.

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

int cardinalidade(char *conjunto)
{
    int contador = 0, indice = 0;

    while (1)
    {
        if (conjunto[indice] == ' ') // Se o elemento analisado for ' ' entao este foi o ultimo elemento.
        {
            break; 
        }

    }

    indice++;
    contador++; // Conta o numero de elementos no vetor.

    return contador;
}

 char *criaConjunto()
 {
       char flag = '!', *conjunto;
       int indice = 0;

       while (flag != '@')
       {
           printf("ELEMENTO %i: ", indice + 1);
           scanf("%c", &flag); // Armazeno o valor lido em uma variavel temporária.

           indice++; // Foi lido mais um elemento.

           conjunto = (char *) malloc (sizeof(char) * indice);  // Aloco um vetor de n posições(depende do numero de elementos preenchidos)
           conjunto[indice] = flag; // Coloco o valor lido anteriormente no conjunto.
        }

        conjunto[indice + 1] = ' '; // Ultimo elemento será o elemento indicando o fim do conjunto.

       return conjunto; // Retornando o endereço do primeiro elemento do conjunto
}

int main()
{
    char *A = criaConjunto();

    printf("|A| = %i", cardinalidade(A));

    return 0;
}
    
asked by anonymous 21.05.2018 / 01:10

1 answer

0

As already indicated the correct one is to use realloc , that way it can go asking for the elements of the form which is already asking, and is increasing the size of the vector as it receives elements.

Embedding in your code would look like this:

char flag = '!', *conjunto = NULL; //o vetor tem de ser inicializado a NULL
int indice = 0;

while (flag != '@')
{
    printf("ELEMENTO %i: ", indice + 1);
    scanf(" %c", &flag);
    //     ^--- este espaço antes serve para consumir a quebra de linha

    conjunto = (char *) realloc (conjunto, sizeof(char) * (indice + 1)); //realloc aqui
    conjunto[indice] = flag;
    indice++;//incremento tem de vir no fim senão o 1 elemento vai para a posição 1 e não 0
}

No realloc indicates which vector to reallocate, which in the example is conjunto , and what size to reallocate. The first time realloc is called with the NULL vector, in which case it behaves as a malloc . Notice that I had to change the increment from indice to the end of while to ensure that the first element is stored in 0 position, but keeping the allocation of the correct size, which is indice + 1 . >

You also have to assign the end of the string with the correct terminator to printf , and ensure there is room for it. Since according to your algorithm you also want to put a space, then you can do so:

//+2 => reservaço tamanho para o espaço e terminador
conjunto = (char *) realloc (NULL, sizeof(char) * (indice + 2)); 
conjunto[indice++] = ' '; 
conjunto[indice] = '
while (1)
{
    if (conjunto[indice] == ' ') // Se o elemento analisado for ' ' entao este foi o ultimo elemento.
    {
        break; 
    }
}
'; //coloca o terminador no fim

With the terminator you can already print the vector in while , if you wish.

Just as a final note, notice that it has an infinite cardinalidade effectively in the indice function:

char flag = '!', *conjunto = NULL; //o vetor tem de ser inicializado a NULL
int indice = 0;

while (flag != '@')
{
    printf("ELEMENTO %i: ", indice + 1);
    scanf(" %c", &flag);
    //     ^--- este espaço antes serve para consumir a quebra de linha

    conjunto = (char *) realloc (conjunto, sizeof(char) * (indice + 1)); //realloc aqui
    conjunto[indice] = flag;
    indice++;//incremento tem de vir no fim senão o 1 elemento vai para a posição 1 e não 0
}

Since while is not incrementing, this %code% will never end because it never goes out of the same caratere. In addition, there are no counts in there which is what I suspect I wanted to do.

    
21.05.2018 / 13:15