Dynamiczna tablica struktur - problem

0

Cześć,

Mam spory problem z zadaniem polegającym na napisaniu programu, który będzie sortował tablicę struktur według średniej arytmetycznej elementów. Użytkownik podaje liczbę struktur N i liczbę elementów E w każdej strukturze. W tego co rozumiem muszę stworzyć tablicę struktur (dynamiczną, gdyż nie wiem ile tych struktur będzie), a każda struktura będzie w sobie zawierała tablicę (również dynamiczną) w której będzie E wartości (typu int) oraz jedna zmienna przechowująca średnią z E elementów.
Wszelkie próby zakończyły się niepowodzeniem, o ile statycznie jestem w stanie to zrobić, to dynamiczna alokacja mnie przerasta, bardzo proszę o pomoc. Dodam, że kod musi być napisany w C.

Pozdrawiam

0

Mój pomysł opierał się na dynamicznej alokacji tablicy n, później definiuję strukturę i w niej odwołuję się do tablicy (już na tym etapie wyskakiwały błędy, natomiast zupełnie nie wiem jak stworzyć tablicę takich struktur :/ Niestety w kodzie nie widać gwiazdek, jak mogę to zmienić?

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

int main (){
int N,n; // N - liczba struktur, n - liczba elementow tablicy w strukturze
int * wsk_n;
    wsk_n = (int *) malloc(n * sizeof(int));
        if (wsk_n == NULL){
            puts("Przydzial pamieci (tablica n) nie powiodl sie.");
            exit(EXIT_FAILURE);
        }
struct struktura{
    int *wsk_n;
    int srednia;
};
return 0;
}
0

Autor tematu pisał, że założeniem jest język C, co zresztą widać po zastosowaniu puts() (którego de facto odradzam stosować, a tym bardziej gets!)
Do autora:
Spróbuj na początek stworzyć typ struktury, który potem wywołasz do życia - wykorzystaj typedef

typedef struct
{
    int *data;    /* Wszystkie elementy w strukturze */
    int E;         /* Tak jak mowiłeś - średnia */
} dataStruct_t;

/* Teraz możesz wykorzystać to aby utworzyć tablicę typu który zdefiniowałeś wyżej.
 * Oczywiście musisz jeszcze zaalokować odpowiednią ilość pamięci na tablicę, którą zadeklarowałem Ci poniżej: */
dataStruct_t *structArray;
0

Bartosz - bardzo dziękuję za odpowiedź. Czy chodzi o coś takiego?

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


int main (){

int N=5,n=4;

typedef struct
{
    int * data;
    int E;
} dataStruct_t;

dataStruct_t *structArray;
structArray = (dataStruct_t*) malloc(N * sizeof(dataStruct_t));


int * data;
data = (int *) malloc(n * sizeof(int));

// test
structArray[1].E=7; //dziala
structArray[1].data[0]=2; // nie dziala
printf("%d %d", structArray[1].E,structArray[1].data[0]);

return 0;
}

Na próbę zadeklarowałem N i n, a także wprowadziłem wartości do struktury, program się kompiluje, ale otrzymuję błąd przy próbie odczytania wartości elementu z tablicy data

1

Super, o to chodziło ;)

Ale tutaj popełniasz błąd. Alokujesz osobną tablicę data:

int * data;
data = (int *) malloc(n * sizeof(int));

Ale potem odwołujesz się do niezaalokowanej tablicy data w strukturze:

structArray[1].data[0]=2; // nie dziala

Zaalokuj odpowiednią pamięć dla każdej tablicy w każdej strukturze.

edit:
Podpowiedź: Użyj pętli i wykorzystaj malloc dla tablicy do której odwołasz się w strukturze ;)

0

Dziękuję za cenny wskazówki, niestety to zadanie wciąż przerasta moje rozwijane od niedawna zdolności programistyczne ;) Będę wdzięczny za wyjaśnienie jak to powinno wyglądać, bo czekam mnie jeszcze wiele godzin zabawy by skończyć ten projekt..

1

Wcale Cię to nie przerasta. Wręcz przeciwnie, już to nawet zrobiłeś:

int * data;     /* Tutaj poprawnie zrobiłeś deklarację wskaźnika  */
data = (int *) malloc(n * sizeof(int));  /* Który potem uczyniłeś pierwszym elementem zaalokowanej tablicy */
 
// test
structArray[1].E=7; //dziala          /* Odwołujesz się do elementu E */
structArray[1].data[0]=2; // nie dziala /* I tak samo do elementu  .data jednak to nie TEN element  data  jest zaalokowany! */

Dokładnie tak samo jak alokujesz pamięć dla zmiennej data zadeklarowanej poza strukturą zaalokuj pamięć dla zmiennej data w stworzonej strukturze. Odwołuj się do wskaźnika data dokładnie tak samo jak odwołałeś się do pola E

Po prostu:
Stwórz pętlę w której będziesz odwoływał się do każdej kolejno struktury (w obecnym kodzie odwołałeś się do drugiej struktury w tablicy struktur) i w pętli tej kolejno alokuj pamięć dla pola data dokładnie tak samo jak zrobiłeś to dla wskaźnika data zadeklarowanego poza strukturą ;)

2

Dobrze kombinowałeś, ale trochę musisz jeszcze popracować nad zrozumieniem wskaźników. Poniżej przykład jak można to zrobić

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

struct i32array {
    uint32_t size;
    int32_t *data;
};

void init_i32array(struct i32array *arr, uint32_t size) {
    if (arr) {
        arr->data = calloc(size, sizeof(int32_t));
        arr->size = arr->data ? size : 0;
    }
}

void cleanup_i32array(struct i32array *arr) {
    free(arr->data);
    arr->size = 0;
}



int main(int argc, char const *argv[]) {
    size_t N = 10, E = 5;

    struct i32array *arrays = calloc(N, sizeof(struct i32array));
    if (!arrays) {
        perror("something went wrong, exiting");
        exit(1);
    }


    for (size_t i = 0; i < N; ++i) {
        init_i32array(&arrays[i], E);
    }

    // do rest here
    // ...

    return 0;
}
0

Dzięki, przeanalizuję to podejście ;) Na szczęście udało mi się napisać odpowiednią pętlę i wydaje mi się, że otrzymałem strukturę danych o jaką mi chodziło. Teraz czeka mnie losowe wypełnienie tej struktury, liczenie średnich arytm i ważonych, sortowanie itp. Mam nadzieję, że dam radę ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1