• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dynamiczna alokacja tablicy struktur

0 głosów
226 wizyt
pytanie zadane 3 lipca 2018 w C i C++ przez qlucha Obywatel (1,790 p.)
edycja 5 lipca 2018 przez qlucha

Mam prośbę, prosiłbym o ocenę i  poradę , czy ten schemat rezerwacji dynamicznej struktury tablic jest poprawnie napisanym kawałkiem kodu czy zawiera gdzieś rażące błędy. Chodzi mi o sposób rezerwacji pamięci dla tablicy struktur ,a nie o same dane czy nazywanie zmiennych. Dzięki za poświęcony czas .smileyyes

#include <iostream>
struct nazwa_typu_struktury
{
    std::string name;
    int age;
    double average;
};

int main()
{
    int ile = 2;

    nazwa_typu_struktury *wskaznik = new nazwa_typu_struktury [ile];
    const nazwa_typu_struktury *adres_poczatkowy = (nazwa_typu_struktury *)wskaznik;

    //zapis danych do pol dynamicznej struktury
    int i = 1;
    while(i <= ile){

      std::cout << "Wprowadz Imie nr."<< i << " :" ;
      std::cin  >> wskaznik->name;             //Metoda 1 dostepu do pola dynamicznej struktury
      std::cout << "Wprowadz Wiek :" ;
      std::cin  >> wskaznik->age;
      std::cout << "Wprowadz Srednia :" ;
      std::cin  >> wskaznik->average;
      std::cout << std::endl;

      i++;
      wskaznik++;
    }

    wskaznik = (nazwa_typu_struktury *)adres_poczatkowy;

    //odczyt danych z pol dynamicznej struktury
    i = 1;
    while(i <= ile){

      std::cout << "Imie nr."<< i << " == " << (*wskaznik).name     << std::endl;  //Metoda 2 dostepu do pola dynamicznej struktury
      std::cout << "Wiek    "     << " == " << (*wskaznik).age      << std::endl;
      std::cout << "Srednia "     << " == " << (*wskaznik).average  << std::endl;
      std::cout << std::endl;
      i++;
      wskaznik++;
    }

    delete wskaznik;


    return 0;
}

Prośba o ponowną  ocenę smileyyes

KOD PO POPRAWIE :

#include <iostream>
#include <string>
struct type_name
{
    std::string name;
    int age;
    double average;
};

int main(void)
{
    int items = 2;

    type_name *dynamic_pointer = new type_name [items];
    const type_name *address_beginning = dynamic_pointer;

        //zapis danych do pol dynamicznej struktury
        for(int i = 1; i <= items; ++i){

            std::cout << "Wprowadz Imie nr."<< i << " :" ;
            std::cin  >> dynamic_pointer->name;             //Metoda 1 dostepu do pola dynamicznej struktury
            std::cout << "Wprowadz Wiek :" ;
            std::cin  >> dynamic_pointer->age;
            std::cout << "Wprowadz Srednia :" ;
            std::cin  >> dynamic_pointer->average;
            std::cout << std::endl;

            dynamic_pointer++;
        }

        dynamic_pointer = (type_name *)address_beginning;

        //odczyt danych z pol dynamicznej struktury
        for(int i = 1; i <= items; ++i){

            std::cout << "Imie nr."<< i << " == " << (*dynamic_pointer).name     << std::endl;  //Metoda 2 dostepu do pola dynamicznej struktury
            std::cout << "Wiek    "     << " == " << (*dynamic_pointer).age      << std::endl;
            std::cout << "Srednia "     << " == " << (*dynamic_pointer).average  << std::endl;
            std::cout << std::endl;

            dynamic_pointer++;
        }

    delete [] address_beginning;


    return 0;
}
/** TEST
    std::cout << "adres dynamic_pointer   ==> " << dynamic_pointer   << std::endl;
    std::cout << "adres address_beginning ==> " << address_beginning << std::endl;
*/

Po dogłębnej analizie ponowna edycja kodu chyba najlepsza wersja prosiłbym o zerknięcie na kod i o ocenę :))

#include <iostream>
#include <string>
#include <cstddef>
struct users
{
    std::string name;
    unsigned int age;
    double average;
};
int main()
{
    users *dynamic_pointer = new users [3];

        for(std::size_t i = 0; i < 3; ++i){

                std::cout << "Insert name nr."<< i + 1 << " :";
                std::cin  >> dynamic_pointer[i].name;
                std::cout << "Insert age  :";
                std::cin  >> dynamic_pointer[i].age;
                std::cout << "Insert average :";
                std::cin  >> dynamic_pointer[i].average;
                system("cls");
        }

       for(std::size_t j = 0; j < 3; ++j){

                std::cout << "Name nr." << j + 1 << " :" << dynamic_pointer[j].name << '\n'
                          << "age       :" << dynamic_pointer[j].age     << '\n'
                          << "average   :" << dynamic_pointer[j].average << '\n' << '\n';
        }

    delete [] dynamic_pointer;

}

 

komentarz 5 lipca 2018 przez qlucha Obywatel (1,790 p.)

@mokrowski,  Witam ,mam nadzieję że nie zamęczam,  rozważyłem za i przeciw i przeanalizowałem uwagi i zamieściłem nowy kawałek kodu, prosba, :)) mógłbyś zerknąć i ocenić dzieki za czas.yes 

komentarz 5 lipca 2018 przez mokrowski VIP (110,820 p.)
Ogólnie, jest ok. Oczywiście zawsze coś da się poprawić. Z rzeczy istotnych acz już w takiej objętości kodu kosmetycznych:

1. Sensownie jest zdefiniować stałą wielkości tablicy (u Ciebie 3) tak aby można było ją ustawić w kodzie w 1 miejscu a użycie nazwy jasno komunikowało że chodzi o wielkość kontenera-tablicy. Lepiej w kodzie nie mieć "wartości magicznych" bo jak kod będzie większy to ktoś zada pytanie: a skąd te dziwne 3 i dlaczego 3?

2. Używanie system(...) to dość niebezpieczny nawyk ale z kolei w takim małym przykładzie jakoś ten ekran trzeba wyczyścić...

3. W zasadzie użytkownik może popełnić błąd we wprowadzaniu danych i wtedy kod będzie mało na to odporny (czytanie z std::cin)

Ogólna opinia, nie warto już "cyzelować" bo i tak wiele cię to nie nauczy a szukanie problemów to raczej już obsesyjna pedanteria...
komentarz 5 lipca 2018 przez qlucha Obywatel (1,790 p.)
Ok dzięki za odpowiedz, walidacja danych wejściowych jest pominięta w tym kodzie ale jestem świadom problemu i biblioteki cctype , oraz sam napisałem dla siebie funkcje walidującą dane wejściowe.    

Zamiast system() jakie rozwiązanie byś polecał, prawdopodobnie chodzi o przenośność na inny system operacyjny się domyślam.

Jest to kod edukacyjny wiadomo. I takie dane jeśli chodzi o dane użytkownika prawdopodobnie powinno się alokować automatycznie a nie dynamicznie bo po użyciu operatora delete tracimy dane . Ale chodziło o przetrenowanie przykładu i jego zastosowanie. Dzieki za odp.
komentarz 5 lipca 2018 przez mokrowski VIP (110,820 p.)

Najlepiej wyczyścić chyba dla GNU/Linux tak:

cout << "\033[2J\033[1;1H";

Dla MS Windows masz odpowiednie wywołania: https://support.microsoft.com/pl-pl/help/99261/how-to-performing-clear-screen-cls-in-a-console-application

Ale nie wygłupiaj się.. To ma być prosty przykład a nie popis "jak to można zrobić profi-cool" :)

komentarz 5 lipca 2018 przez qlucha Obywatel (1,790 p.)

Ok, dzieki . Nic lecę dalej z materiałem zobaczymy co z tego będzie.yes

2 odpowiedzi

+1 głos
odpowiedź 3 lipca 2018 przez Patrycjerz Mędrzec (186,970 p.)
wybrane 3 lipca 2018 przez qlucha
 
Najlepsza

Jest na prawdę sporo błędów.

  1. const nazwa_typu_struktury *adres_poczatkowy = (nazwa_typu_struktury *)wskaznik;

    Rzutowanie jest tutaj bezcelowe.

  2. int i = 1;
    while(i <= ile){

    Do takich rzeczy stosuje się pętlę for.

  3. wskaznik = (nazwa_typu_struktury *)adres_poczatkowy;

    Znowu bezcelowe rzutowanie.

  4. delete wskaznik;

    Powinno być:

    delete[] adres_poczatkowy;
    
  5. Ogólnie kod jest mało bezpieczny. Nie trudno w nim o pomyłki. Najlepiej używać operatora indeksu dla tablic, a w większości przypadków unikać w ogóle korzystania z "gołych" tablic dynamicznych, zastępując je kontenerami biblioteki standardowej.

2
komentarz 3 lipca 2018 przez monika90 Pasjonat (22,980 p.)
powinno być delete[] i jeszcze #include <string> na początku
komentarz 3 lipca 2018 przez Patrycjerz Mędrzec (186,970 p.)
Racja, zapomniałem o nawiasach. Dołączenie nagłówka `string` nie jest konieczne w MinGW, więc nie jest to wielki błąd (choć pisząc kod multiplatformowy należy na to uważać).
komentarz 3 lipca 2018 przez qlucha Obywatel (1,790 p.)

Ok dzięki za odpowiedz. yes

 

komentarz 4 lipca 2018 przez qlucha Obywatel (1,790 p.)

wprowadziłem parę poprawek prośba o ponowną ocenę z góry dzieki.smileyyes

+1 głos
odpowiedź 3 lipca 2018 przez RafalS VIP (113,290 p.)
Rezerwacja jest dobra, za to do całej reszty bym sie przyczepił :D
komentarz 3 lipca 2018 przez Hiskiel Pasjonat (22,800 p.)
Do czego dokładnie? Ja bym się czepiał polskich nazw oraz castowania (obj)obj. Nie wiem co tu można jeszcze doczepić.
komentarz 3 lipca 2018 przez qlucha Obywatel (1,790 p.)

można wymienić co jest do du... smiley \. Lubie konstruktywną krytykę po to zamieściłem ten kod licząc na konstruktywną krytykę.  Dzieki za odpowiedz.

komentarz 3 lipca 2018 przez RafalS VIP (113,290 p.)
const nazwa_typu_struktury *adres_poczatkowy = (nazwa_typu_struktury *)wskaznik;

niepotrzebne rzutowanie.

czemu pętla while zamiast fora?

Chociaż jeśli jest to jest kod edukacyjny, żeby pokazać, że tak też można to sie nie czepiam tej pętli.

Pomieszanie jezyków takie everytime when you czujesz sie bad

Podobne pytania

0 głosów
1 odpowiedź 1,096 wizyt
pytanie zadane 24 lipca 2017 w C i C++ przez Dooky Początkujący (480 p.)
0 głosów
2 odpowiedzi 385 wizyt
pytanie zadane 24 stycznia 2017 w C i C++ przez spvce Początkujący (260 p.)
0 głosów
1 odpowiedź 98 wizyt
pytanie zadane 19 listopada 2018 w C i C++ przez Roman1212 Początkujący (370 p.)
Porady nie od parady
Forum posiada swój własny chat IRC, dzięki któremu będziesz mógł po prostu pogadać z innymi Pasjonatami lub zapytać o jakiś problem. Podstrona z chatem znajduje się w menu pod ikoną człowieka w dymku.IRC

66,451 zapytań

113,207 odpowiedzi

239,680 komentarzy

46,704 pasjonatów

Przeglądających: 264
Pasjonatów: 10 Gości: 254

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...