Witamy na forum PC Format Zapraszamy do REJESTRACJI


Użytkownicy przeglądający ten wątek: 1 gości

Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)

#1
Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
Jestem początkujący programuje w ANSI C
Muszę przerobić poniższą strukturę tak aby bazowała na dynamicznej pamięci.
Kod:
#include <stdio.h>
#include <stdlib.h>
#define n 20

struct adres
{
     char ulica[n];
     int numer;
     char miasto[n];
     char panstwo[n];
};

struct dane_osobowe
{
     char imie[15];
     char nazwisko[30];
     int wiek;
     struct adres add;
     char plec[10];
     int nrpesel;
};

int main()
{

struct dane_osobowe osoba1;

   printf ("Imie: ");
   scanf ("%s",osoba1.imie);
   printf ("Nazwisko: ");
   scanf ("%s",osoba1.nazwisko);
   printf ("Wiek: ");
   scanf ("%d",&osoba1.wiek);
   printf("\n");
   printf ("Adres\n");
   printf ("Ulica: ");
   scanf ("%s",osoba1.add.ulica);
   printf ("Numer mieszkania: ");
   scanf ("%d",&osoba1.add.numer);
   printf ("Miasto: ");
   scanf ("%s",osoba1.add.miasto);
   printf ("Panstwo: ");
   scanf ("%s",osoba1.add.panstwo);
   printf("Plec: ");
   scanf ("%s",osoba1.plec);
   printf ("PESEL: ");
   scanf ("%d",&osoba1.nrpesel);
system("PAUSE");
return 0;
}

gdy chcę alokować element "ulica" bez struktury to działa
Kod:
int main()
{
  char *ulica;
  ulica=(char*)malloc(20*sizeof(char));
  system("PAUSE");    
  return 0;
}


ale gdy chcę to samo zrobić w strukturze to już nie działa

Kod:
int main()
{
  struct adres
{
    char *ulica;
    ulica=(char*)malloc(20*sizeof(char));
    int numer;
    char miasto[20];
    char panstwo[20];
};
  system("PAUSE");    
  return 0;
}
 System operacyjny: windows_xp_2003 Przeglądarka: opera
#2
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
Kod:
typedef struct
{
  char *ulica;
  char *miasto;
}adres;
//
int main()
{
  adres dom;
  dom.ulica=(char*)malloc(30*sizeof(char));
  dom.miasto=(char*)malloc(30*sizeof(char));
//
  free(dom.ulica);
  free(dom.miasto);
}
 System operacyjny: windows_xp_2003 Przeglądarka: firefox
#3
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
Atup
sizeof(char) zawsze zwraca 1, choćby nie wiem ile bitów miał char na Twojej architekturze - więc możesz sobie to opuścić.
malloc() zwraca void* - więc rzutowanie na char* jest niepotrzebne. Chyba, że piszesz w C++, ale wtedy raczej użyłbyś new/delete i new[]/delete[].Oczko

Atslawciu15 - scanf("%s", ...) jest niebezpieczne - spróbuj wpisać trzydzieści znaków bez spacji jako imię. Nadpisane zostaną pewnie kolejne zmienne, czego konsekwencji akurat nie poczujesz, bo za chwilę znów je nadpisujesz. Ale zrób to samo z ostatnim wczytywaniem - bum, program się wywali, bo próbowałeś nadpisać nie swoją pamięć.Oczko
Użyj fgets() albo scanf("%19s", ...) aby zabezpieczyć się przed nadpisaniem pamięci (19, bo jest o 1 mniejsze od 20, czyli rozmiaru Twojej tablicy - ten jeden znak potrzebny jest na '\0' czyli terminator c-stringa.
 System operacyjny: windows_xp_2003 Przeglądarka: firefox
#4
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
(18.05.2011, 12:26)~Anonim napisał(a): Atup
sizeof(char) zawsze zwraca 1, choćby nie wiem ile bitów miał char na Twojej architekturze - więc możesz sobie to opuścić.
malloc() zwraca void* - więc rzutowanie na char* jest niepotrzebne. Chyba, że piszesz w C++, ale wtedy raczej użyłbyś new/delete i new[]/delete[].Oczko
Odpuść sobie takie wypowiedzi.
Nie wiesz, nie komentuj.

1. Co z tego, że sizeof zwróci np. 20, a nie 100? Nie ma to znaczenia, bo sizeof liczy wielkość typu, a nie jego długość, strlen służy do zwrócenia długości,
2. Brak potrzeby rzutowania? Jest szansa, że niektóre kompilatory rzutują niejawnie, ale część tego nie obsługuje,
3. Jeżeli pamięć ma być dynamicznie alokowana (ściśle dopasowana ilość pamięci) to Twoje new i delete możesz sobie wsadzić tam, gdzie słońce nie dochodzi. Wiesz, że dojdzie do nadpisania w razie konieczności powiększenia? Aby do tego nie dopuścić używamy malloca.
 System operacyjny: windows_seven Przeglądarka: firefox
#5
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
Odpowiadając
1) A to, że sizeof(char) zawsze zwróci 1. Więc pisanie n * sizeof(char) ma tyle samo sensu co pisanie n * 1 - czyli lepiej po prostu opuścić całą zabawę i napisać n, prawda?Oczko
Funkcja strlen() nie ma tutaj nic do rzeczy, bo zamiast niej rozmiar ustawiono w tej linijce ręcznie: dom.ulica=(char*)malloc(30*sizeof(char));. Więc zastępowanie sizeof() funkcją strlen() wyglądałoby tak: malloc(30 * strlen(costam));. Ma to sens? Nie. Więc o co cała sprawa?

2) Brak, bo w C rzutowanie T* <-> void* jest jak najbardziej legalne i automatyczne (choć może być dość niebezpieczne), a malloc() zwraca właśnie void*. Dlatego w C rzutowanie jest tam kompletnie niepotrzebne. Lepiej jest je opuścić, bo jeśli tam będzie, to przykryje nam błąd konwersji int -> T* jeżeli zapomnimy o dołączeniu stdlib.h.Oczko
W C++ rzutowanie T* -> void*, również jest automatyczne, ale już void* -> T* wyrzuci Ci błąd, bo taka konwersja nie jest automatyczna. Jeżeli już koniecznie chcesz, to możesz wymusić taką konwersję za pomocą rzutowania - najlepiej static_cast<> (choć c-style cast oczywiście również zadziała).
Reasumując, zerwałem się z tej choinki, na której rzeczywiście czyta się standard języka, którego się używa.Język

3) Huh? Mogę prosić jeszcze raz? Przy new/delete nie ma w ogóle możliwości zmiany rozmiaru takiej jaką daje realloc() - więc o czym mowa? Jeżeli już potrzebowałbym czegoś takiego, to można po prostu skopiować dane do większego bufora i zwolnić stary*. Czyli zrobiłbym mniej więcej to samo co realloc(). Z tym, że ręcznie to raczej bym tego nie robił, bo i po co, skoro tyle jest gotowych kontenerów w STL i Boost.Oczko

*) Przykład:
Kod:
T* bufor = new T[50];
// wypelniam bufor, brakuje mi pamięci,
// alokuje wiec nowy bufor
T* tmp = new T[100];
// kopiuje sobie zawartość starego bufora do nowego
for (size_t i = 0; i < 50; ++i) { tmp[i] = bufor[i]; }
// zwalniam stary, niepotrzebny bufor
delete[] bufor;
bufor = tmp;
tmp = nullptr; // ot, tak dla higieny
//...
delete[] bufor;
Voilà. Więc o jakim "nadpisaniu" pisałeś, którego to podobno malloc() uniknie? Poza tym, akurat w świecie C++ to malloc/calloc/realloc/free można sobie odpuścić, bo nie oferują inicjalizacji obiektów. Kopiowanie złożonych obiektów za pomocą memcpy() też może się źle skończyć.Oczko
 System operacyjny: windows_xp_2003 Przeglądarka: firefox
#6
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
char to nie jest char*.
Mają zupełnie inne rozmiary ze względu na wskaźnik, więc mnożenie jest całkowicie uzasadnione.

Jeżeli zrobisz powiedzmy new int[10]; to żeby powiększyć tą tablicę nie użyjesz new bez skasowania danych Krzywy Trzeba malloca. O to mi chodziło.
 System operacyjny: windows_seven Przeglądarka: firefox
#7
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
A gdzie Ty przepraszam char* w połączeniu z sizeof widziałeś w tym wątku?Oczko Ja ciągle pisałem o sizeof(char), które (tak, po raz trzeci powtarzam) zawsze zwraca 1 - czyli pisanie malloc( N * sizeof(char) ) jest niszczeniem sobie klawiatury, wystarczy malloc( N ).

Cytat:Jeżeli zrobisz powiedzmy new int[10]; to żeby powiększyć tą tablicę nie użyjesz new bez skasowania danych Krzywy Trzeba malloca. O to mi chodziło.
Bez skasowania się nie obejdzie, ale co z tego? realloc i tak zaalokuje nową pamięć, skopiuje dane i zwolni starą.Oczko
Poza tym w C++ i tak raczej nie użyjesz malloc() bo nie będą Ci działać (szczególnie nietrywialne) konstruktory, destruktory, etc. Mieszanie malloc()/free() do C++ zwykle jest kompletnie niepotrzebne.

Jeśli już chciałbym mieć tablicę, którą później mogę sobie dowolnie rozszerzać, to na pewno nie będę się bawił malloc()/realloc(), kiedy mogę użyć std::vector.Oczko
Kod:
vector<int> v(10);
v.push_back(5);
v.resize(122);
//etc

Wracając do początku, op napisał, że kod jest w C. Język
 System operacyjny: windows_xp_2003 Przeglądarka: firefox
#8
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
Kod:
#include <stdio.h>
#include <stdlib.h>
#define N 100

struct adres
       {
       char *ulica;
       int *numer;
       char *miasto;
       char *panstwo;
       };
  
       struct dane_osobowe
       {
       char *imie;
       char *nazwisko;
       int *wiek;
       struct adres add;
       char *plec;
       }tab;
      
      
void wczytajOsobe(struct dane_osobowe *osoba);
void drukuj(struct dane_osobowe *osoba);

int main()
{
tab.imie=(char*)malloc(30*sizeof(char));  
tab.nazwisko=(char*)malloc(30*sizeof(char));
tab.wiek=(int*)malloc(30*sizeof(int));
tab.plec=(char*)malloc(30*sizeof(char));
tab.add.ulica=(char*)malloc(30*sizeof(char));
tab.add.numer=(int*)malloc(30*sizeof(int));
tab.add.miasto=(char*)malloc(30*sizeof(char));
tab.add.panstwo=(char*)malloc(30*sizeof(char));  

struct dane_osobowe *wsk=NULL;
wsk=&tab;
int i;

for (i=0; i<2; i++)
{
wczytajOsobe(wsk+i);
printf ("\n");      
}

printf ("\n\n\n");

for (i=0; i<2; i++)
{
drukuj(wsk+i);
printf ("\n");      
}

free(tab.imie);
free(tab.nazwisko);
free(tab.wiek);
free(tab.plec);
free(tab.add.ulica);
free(tab.add.numer);
free(tab.add.miasto);
free(tab.add.panstwo);

  system("PAUSE");    
  return 0;
}

void wczytajOsobe(struct dane_osobowe *osoba)
{
    
    printf ("Imie: ");
    scanf("%s",(*osoba).imie);
    printf ("Nazwisko: ");
    scanf ("%s",(*osoba).nazwisko);
    printf ("Wiek: ");
    scanf ("%d",&(*osoba).wiek);
    printf ("Adres\n");
    printf ("Ulica: ");
    scanf ("%s",(*osoba).add.ulica);
    printf ("Numer mieszkania: ");
    scanf ("%d",&(*osoba).add.numer);
    printf ("Miasto: ");
    scanf ("%s",(*osoba).add.miasto);
    printf ("Panstwo: ");
    scanf ("%s",(*osoba).add.panstwo);
    printf("Plec: ");
    scanf ("%s",(*osoba).plec);
    
}

void drukuj(struct dane_osobowe *osoba)
{
    
    printf ("Imie: %s\n",(*osoba).imie);
    printf ("Nazwisko %s\n",(*osoba).nazwisko);
    printf ("Wiek %d",(*osoba).wiek);
    printf ("Adres\n");
    printf ("Ulica %s\n",(*osoba).add.ulica);
    printf ("Numer mieszkania %d\s",(*osoba).add.numer);
    printf ("Miasto %s\n",(*osoba).add.miasto);
    printf ("Panstwo %s\n",(*osoba).add.panstwo);
    printf ("Plec %s\n",(*osoba).plec);
    
}

Zadeklarowałem dynamicznie elementy.
Chciałbym aby struktura tab była zapisywana w dynamicznej tablicy bo obecnie w pierwszej pętli przy drugim krążeniu wywala błąd.
Nie potrafię zmienić %s na fgets()
Kod:
scanf("%s",(*osoba).imie);
zamieniam na
Kod:
fgets((*osoba).imie);
wypisuje 72 C:\Dev-Cpp\main.c too few arguments to function `fgets'
 System operacyjny: windows_xp_2003 Przeglądarka: opera
#9
RE: Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc)
Kod:
char* fgets(char* str, int size, FILE *stream);
Znasz choć trochę angielski? Komunika błędu jasno informuje, że funkcja fgets ma w deklaracji więcej argumentów niż jeden.
Kod:
fgets(osoba->imie, 30, stdin);
Żaden kraj nie może być dobrze rządzony, dopóki wszyscy jego obywatele nie będą pamiętać, że oni są strażnikami prawa.




 System operacyjny: windows_xp_2003 Przeglądarka: firefox
Programy: Polecane / Nowe / Inne




Podobne wątki (Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc))
Wątek: Autor Odpowiedzi: Wyświetleń: Ostatni post
  Niuanse adresacji pamięci przez funkcje malloc() wanhelsing 4 2484 28.02.2014, 12:00
Ostatni post: wanhelsing
  Zasada przydzielania pamięci przez funkcję - malloc() w języku c. wanhelsing 2 2903 29.01.2014, 19:34
Ostatni post: wanhelsing
  Jak Przerobić ELFBOTA Hassano 1 4400 30.04.2013, 15:34
Ostatni post: MiXXen

Skocz do:


Wybrane wątki (Muszę przerobić strukturę tak aby wykożystywała dynamiczną pamięć. (malloc))
Wątek: Autor Odpowiedzi: Wyświetleń: Ostatni post
  Oczekiwanie na Akcje przycisku wanhelsing 8 1767 01.03.2020 19:44
Ostatni post: Szachista
Toungue Wybór szkoły średniej przez potencjalnego programistę Zikinan 1 2090 09.02.2020 15:58
Ostatni post: dzikuu86
  Skrypt pod sklep internetowy Talcia 4 4547 14.12.2019 19:48
Ostatni post: hexopex760
  Poszukuję pomysłu na prosty program ;) janciu96 5 11023 13.12.2019 23:32
Ostatni post: Ajgor
  Programowanie Batch (CMD) Informatyk2019 0 3144 11.12.2019 18:30
Ostatni post: Informatyk2019
  [JavaScript] Znajdowanie przedziału czasu rafal12999 0 1398 10.12.2019 17:58
Ostatni post: rafal12999
  Przekazywanie wskaźnika przez referencję w Qt Trojan3000 3 10793 10.12.2019 13:16
Ostatni post: Ajgor
  Proszę o pomoc w uzupełnieniu ankiety dt. Zawodu Programisty MaleMonki 0 1897 17.11.2019 12:47
Ostatni post: MaleMonki
  Spring framework – jakie strony polecacie do nauki? olek23 5 5321 15.11.2019 15:57
Ostatni post: Alsenas
  Programowanie windy (problem) w C++ mysza2323 2 4147 06.11.2019 23:04
Ostatni post: mysza2323
  Programy w C ~Anonim 1 4515 22.10.2019 17:48
Ostatni post: Szachista
  Książki do nauki C# olek23 14 14958 17.10.2019 13:06
Ostatni post: Ajgor
  Wyświetlanie informacji z bazy danych na stronie www PitPlay 1 5737 16.09.2019 11:18
Ostatni post: Ajgor
  Błąd przy uruchamianiu programu w Java z wiersza poleceń Physicist 3 3637 30.08.2019 14:16
Ostatni post: Physicist
  Python z wiersza poleceń Physicist 15 16791 21.08.2019 20:14
Ostatni post: Physicist