Как вывести содержимого динамического массива в консоли на языке Си без мусора

Всем привет! Есть ошибка но не могу ее найти. При печати содежимого динамического массива в консоль выводятся содержимое лишних ячеек памяти. Главная цель была сделать функцию типа void archivoToArreglo, которая содержимое файла "articulos.bin" разбивает на два динамических массива: arreEconomicos и arreCostosos. Эта функция принимает в качестве аргументов: название файла, указатели на два массива, их длинну и цену. Функция разделяет файл на два массива с учетом указанной цены: меньшее указанной цены (данные уходят в arreEconomicos) и более/равно указанной цене (данные уходят в массив arreCostosos). Также через указатели функция должна сохранить длинны двух массивов (validosE и validosС). В итоге получаю два массива, при попытке печати в консоль по порядку, первый- выводится без ошибок, второй- печатает содержимое лишних ячеек памяти (мусор) выходя за пределы массива. При этом если поменять местами порядок печати массивов, то ситуация повторяется (первый выводится без ошибок а второй массив печатает содержимое лишних ячеек.

Итак, здесь определяю файл и struct stArticulo:

#define ARTICULOS "articulos.bin"
typedef struct
{
int id;
float precio;
} stArticulo;

Далее функция main

int main(void) {
    cargarArchivo(ARTICULOS,3);// эта функция для заполнения файла с которым далее работаем
    //создаем переменные для динамических массивов и их длинну
    stArticulo* arreEconomicos;// дешевые товары
    int* validosE;//длинна массива дешевых т
    stArticulo* arreCostosos; //дорогие товары
    int* validosC;//длинна массива дорогих т
    printf("\nEnter a number: ");
    scanf("%d", &precio); // считываем цены, которая будет делить файл на два массива
    archivoToArreglo(ARTICULOS, &arreEconomicos, &arreCostosos, &validosE, &validosC, precio);

    printf("\n La cantidad de economicos: %d",*validosE); 
    printf("\n La cantidad de costosos: %d\n",*validosC);// убеждаемся что ф-я archivoToArreglo вернула нам длинну массивов
    printf("\n El arreglo Economicos: \n");
    muestraArreArti(&arreEconomicos,*validosE); // выводим в консоль дешевые т.
    printf("\n");
    
    printf("\n El arreglo Costos: \n");
    muestraArreArti(&arreCostosos,*validosC);// выводим в консоль дорогие т.
    printf("\n");
    
    return 0;
}

В итоге, при наличии в файле 6 элементов и указании цены 1300 я получаю два массива: arreEconomicos - 2 элемента и arreCostosos - 4 элемента: введите сюда описание изображения И печать содержимого этих массивов. При печати второго массива (arreCostosos) выводит в консоль 8 строк, хотя должно быть 4.
введите сюда описание изображения Здесь все функции использованные в main:

void cargarArchivo (char archivo[], int dimencion)// функция для заполнения архива
{
    stArticulo aux;
    FILE* archi =fopen(archivo, "ab");
    if(archi!=NULL){
        while (dimencion>0) {
            aux=cargarUnRegistro();
            fwrite(&aux, sizeof(stArticulo), 1, archi);
            dimencion--;
        }
    }
    fclose(archi);
}
  • вспомогательная ф-я для считывания даных в консоли
stArticulo cargarUnRegistro(void)
{
    stArticulo Articulo;
    printf("\nIngrese id: ");
    scanf("%d", &Articulo.id);
    printf("\nIngrese el precio: ");
    fflush(stdin);
    scanf("%f", &Articulo.precio);
    return Articulo;;
}

функция для распределения файла по двум массивам

void archivoToArreglo(char archivoNombre[], stArticulo **arregloEconomicos, stArticulo **arregloCaros, int **validosEconomicos,int **validosCaro, float dado)
{
    stArticulo aux;
    int validosE=0; int validosC=0;
    int i=0; int j=0;
    *arregloEconomicos = malloc(sizeof(stArticulo));
    *arregloCaros = malloc(sizeof(stArticulo));
    FILE* archi =fopen(archivoNombre, "rb");
    if(archi!=NULL){
        while((fread(&aux, sizeof(stArticulo),1,archi))>0){
            if(aux.precio<dado){
                validosE++;
                *arregloEconomicos = realloc(*arregloEconomicos, (sizeof(stArticulo))*validosE);
                (*arregloEconomicos)[i]=aux;
                i++;
            } else{
                validosC++;
                *arregloCaros = realloc(*arregloCaros, (sizeof(stArticulo))*validosC);
                (*arregloCaros)[j]=aux;
                j++;
            }
        }
        *validosEconomicos=&validosE;
        *validosCaro=&validosC;
    }
    fclose(archi);
}

функция для печати содержимого массивов в консоль, при использовании которых воспроизводится ошибка:

void muestraArreArti (stArticulo ** arreglo, int validos)
{
    for (int i=0; i< validos; i++){
        printf("\n%d |", (*arreglo)[i].id);
        printf("%.2f |",(*arreglo)[i].precio);
    }
}

Я пробовал разыменовать переменные *validosEconomicos и *validosCaro в main таким образом:

int a = *validosEconomicos; 
int b = *validosCaro; 

и далее a и b использовать в функциях печати массивов

muestraArreArti(&arreEconomicos,a);
muestraArreArti(&arreEconomicos,b);

тогда печать происходит без ошибок. Но суть в том, что нужно использовать *validosEconomicos и *validosCaro и не создавая новые переменные.Возможно ли это?


Ответы (1 шт):

Автор решения: MBo

Переменные длин массивов int* validosE сделайте просто int.
Иначе под них нужно выделять память.

→ Ссылка