Dynamic vector allocation

4

The statement follows:

  

Make a program that reads keyboard numbers and stores them in a   vector dynamically allocated. The user will enter a sequence of   numbers, with no quantity limit. The numbers will be typed one by one   and, in case he wishes to close the data entry, he will   enter the number ZERO. The data must be stored in the memory of this   mode

     
  • Start with a dynamically allocated size 10 vector;
  •   
  • Then, if the allocated vector is full, allocate a new vector the size of the previous vector by adding space to another 10 values   (size N + 10, where N starts with 10);
  •   
  • Copy the already typed values from the starting area to this larger area and free the memory of the initial area;
  •   
  • Repeat this procedure to dynamically expand with 10 more values to the allocated vector each time it is full. So the   vector will be 'expanded' by 10 in 10 values.
  •   

At the end, display the read vector. Do not use the REALLOC function.

I'm pretty fresh yet, so there's probably a lot of wrong things in my code.

I tried to use a second vector, move everything to it, allocate 10 more spaces in the main vector and then move everything to it again.

But when I type, I get to 19 and the program stops. In the first 10, it works perfectly, but then when I go to allocate another 10 (in case the vector would have 20 spaces) it does not work.

Here is the code I did:

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

int main(){
    int *vet, c=1, c2=0, *vet1, aux;

    vet =(int*) calloc(10, sizeof(int));

    do {
        scanf("%d", &aux);

        if (c == 10){

            vet1 = (int*) malloc (c2 * sizeof(int));

            for (int i=0; i<c2+1; i++) vet1[i] = vet[i];    

            vet = (int*) malloc (c2 * sizeof(int));

            for (int i=0; i<c2; i++) vet[i] = vet1[i];

            c = 1;
        }

        c++;
        c2++;
        vet[c2] = aux;

    } while (aux != 0);

    printf("\n\n")    ;
    for (int i=0; i<c2; i++) printf("%d  ", vet[i]);

    system("pause");
    return 0;
}
    
asked by anonymous 14.08.2018 / 18:04

2 answers

4

One of the reasons for the confusion is that the code uses variable names difficult to understand what they mean. With better names one can better follow what is happening. The code does more than it should and falls into some traps.

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

int main() {
    int indice = 0, indiceParcial = 0;
    int *vetor = malloc(sizeof(int) * 10);
    while (1) {
        int valor;
        scanf("%d", &valor);
        if (valor == 0) break;
        vetor[indice++] = valor;
        if (indiceParcial++ == 9) {
            int *vetorAuxiliar = malloc(sizeof(int) * (indice + 10));
            memcpy(vetorAuxiliar, vetor, indice * sizeof(int));
            free(vetor);
            vetor = vetorAuxiliar;
            indiceParcial = 0;
        }
    }
    printf("\n");
    for (int i = 0; i < indice; i++) printf("%d  ", vetor[i]);
}

See running on ideone . And no Coding Ground . Also I put GitHub for future reference .

  • Only declare the variable when you need it
  • You do not need to calloc() and should not cast of the result.
  • I'm not worrying about the test to see if the allocation spoke because in exercise this will not fail
  • This is a typical loop without end since the output is in the core of it does not have to use condition
  • Once the value is entered you must determine whether to continue or exit the loop
  • The first thing you should do is to add the value to the vector
  • Next, it analyzes if the vector has filled up and must proceed with a reallocation and copying
  • When you should recreate you create based on the current size plus 10, according to the statement
  • And use memcpy() which is a ready and reliable function to copy data. You use sizeof in it for the same reason you use it in malloc() , these functions operate based on char , then copy byte per byte, and if you have a number of elements of a multibyte type you have to multiply by that number
  • You can not forget to free the memory of the previous vector
  • Then the new vector created as the default is copied by copying its address ( vetor becomes null after free() , if all goes well)
  • And we zero the partial index that controls when it breaks the limit. It is possible to eliminate this variable and make a indice % 10 , but it will almost certainly be slower since the division is by far the slowest operation of the processor. Or use one thing or another, you need to decide whether you want simpler code or more performance.
  • Maybe it would be better to use a for by reducing the scope of 2 variables.
14.08.2018 / 18:58
0

Following your style ...

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

int main(){
    int *vet, c=0, c2=0, *vet1, aux, N=1;

    vet =(int*) calloc(10, sizeof(int));

    do {

        scanf("%d", &aux);
        if(!aux) break;

        if (c%10 == 0){
            N++;
            vet1 = (int*) malloc (N*10 * sizeof(int));
            for (int i=0; i<(10*(N-1)); i++) vet1[i] = vet[i];    
            free(vet);
            vet = (int*) malloc (N*10 * sizeof(int));
            for (int i=0; i<(10*(N-1)); i++) vet[i] = vet1[i];
            free(vet1);
        }
        c2++;
        vet[c++] = aux;
    } while (aux);

    printf("\n\n");
    for (int i=0; i<c2; i++) printf("%d  ", vet[i]);
    printf("\n");
    free(vet1);
    free(vet);

    return 0;
}
    
14.08.2018 / 18:37