Dynamic vector allocation

Follows the statement:

Make a program that reads keyboard numbers and stores them in a dynamically allocated vector. The user will enter a sequence of numbers, no quantity limit. The numbers will be typed one by one and, if it wants to terminate the data entry, it will enter the number ZERO. The data must be stored in the memory of this Mode

  • start with an allocated vector of size 10 dynamically;
  • after, if the allocated vector is full, allocate a new vector of the size of the previous vector by adding space for 10 more values (size N + 10, where N starts with 10);
  • copy the values already entered from the initial area to this larger area and release the memory of the initial area;
  • Repeat this procedure of dynamically expanding the allocated vector with 10 more values each time it is filled. Thus the Vector will be 'expanded' from 10 to 10 values.

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

I'm quite a newbie yet, so there's probably a lot of things wrong with my code.

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

However, when I go typing I arrive at 19 and the program stops. In the first 10, it works perfectly, but then when I will allocate another 10 (in case the Vector would be with 20 spaces) it does not work.

Follows the code I made:

#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;
}
Author: Maniero, 2018-08-14

2 answers

One of the reasons for the confusion is the code using variable names that are 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 working on ideone. E no repl.it. also I put on GitHub for future reference .

  • only declare the variable when you need it
  • No need calloc() and should not make cast of the result.
  • I'm not worrying about the test to see if the allocation spoke because in exercise so will not fail
  • this is a typical endless loop since the output is in the core of it does not have to use condition
  • as soon as the value is typed it must determine whether it continues or exits the loop
  • the first thing that should operate is to add the value in the vector
  • then parses whether the vector filled and must proceed a relocation and copy
  • when you should recreate you create based on the current size plus 10, as stated
  • and use memcpy() which is ready and reliable function to copy data. You use sizeof in it for the same reason you use in malloc(), these functions operate on the basis of char, then copy byte by byte, and if you have a number of elements of a multibyte type you need to multiply by this number
  • can not forget to free the memory of the vector previous
  • and then you adopt the new vector created as the default 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 is almost certain that it will be slower since splitting is by a large margin the slowest operation of the processor. Or use one thing or another, you need to decide if you want simpler code or more performance
  • maybe it would be better to use a for reducing scope of 2 variables.
 4
Author: Maniero, 2020-07-30 16:23:37

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;
}
 0
Author: thxmxx, 2018-08-14 17:01:26