[C] Funkcja malloc i ostatni element


(Adi Aj) #1

Witam wszystkich. Mam pytanie odnośnie funkcji malloc w języku C.

Tworze tablice dynamiczną za pomocą malloca np z kilkoma liczbami.

Jak mogę wyznaczyć w prosty sposób ostatni element tej tablicy ??

Próbuje cały czas jednak za nic nie mogę dojść do sensownego rozwiązania :frowning:

Potrzebuje to np do takiego zadania które miało by zamienić kolejność elementów (zamiast 1,2,3,4,5 miało by być 5,4,3,2,1). Nie chodzi o sortowanie! Tylko o sam fakt wyznaczenia wielkości tablicy.

Proszę Was o pomoc :slight_smile:


(Ryan) #2

Nie możesz. Musisz znać wielkość zaalokowanego obszaru pamięci. Jednym z możliwych rozwiązań jest trzymanie magicznej wartości w ostatnim polu. Jeśli nie chcesz trzymać tego osobno i używasz MSVC, możesz użyć takiej konstrukcji:

#include 

#include 


typedef struct _MOJE_INTY {

  size_t RozmiarTablicy;

  int Dane[0];

} MOJE_INTY, *PMOJE_INTY;


int main()

{

    // potrzebuje 123 elementow

    PMOJE_INTY mi = (PMOJE_INTY)malloc(123 * sizeof(int) + sizeof(MOJE_INTY));

    mi->RozmiarTablicy = 123;


    // teraz mozesz sie odwolywac do mi->Dane[0] ... mi->Dane[122]

    for (int i = 0; i < mi->RozmiarTablicy; ++i)

        mi->Dane[i] = i * i;

    wprintf(L"%d\n", mi->Dane[7]);


    free(mi);


    return 0;

}

([alex]) #3

double *tb=(double*)malloc(5*sizeof(double));


(Ryan) #4

Ale to nie odpowiada na pytanie: mając tb, powiedz ile elementów jest w tb. :wink:


([alex]) #5

Aha, o to chodzi.

Kiedyś zrobiłem sobie kilka ciekawych funkcji (EDIT: znalazłem późniejsza wersje, podmieniłem.):

#include

(Adi Aj) #6

Hmm pod parłem się waszą wiedzą i troszkę jeszcze doczytałem sobie i mniej więcej rozumiem o co chodzi :wink: Teraz troszkę praktyki i będzie jeszcze lepiej. Jednak powiedzcie mi jeśli możecie.. :wink:

Chciałem napisać program, na razie na sztywno, który miałby wypisywać po kolei elementy tablicy (na sztywno wpisaną) do puki nie trafi na liczbę "3". Napisałem coś takiego :wink:

#include 


int main()

{

  int i;  

  int tab[5] = {1,2,3,4,5};


  for (i=0; tab[i]=2; i++)

  {

        printf("Wartosc: %d \n", tab[i]);      

  }


  system("PAUSE");	

  return 0;

}

Jednak nie działa mi :frowning: teoretycznie mi się wydaje że jest okej jednak zawsze popełniam błąd którego bez pomocy nie potrafię znaleźć :frowning: Jeśli możecie podpowiedzcie troszkę :wink:


(Sawyer47) #7

tab_=2_

= to operator przypisania, a nie równości


([alex]) #8

miałeś na myśli

tab[i]<=2[/code]

?


(Adi Aj) #9

Faktycznie.. pomyliłem się i dałem jedno = za mało :confused: Jednak dalej nie działa.

Sprawdziłem opcję @[alex] i działa :slight_smile: Szczerze mówiąc nie wpadł bym na to :confused: Próbowałem dużo razy ale na to bym nie wpadł :confused: Dzięki wielkie :slight_smile:

A powiedzcie czy mogę w ten sam sposób sprawdzać tablice znaków ?? np char tab[15]="ala ma kota"; i by przerwało pętlę po napotkaniu np pustego znaku np spację??


([alex]) #10

Wiesz, wg mnie mniej by czasu straciłeś sprawdzając to w programie niż straciłeś na napisanie tego postu.

Działą to dokładnie tak samo z tym że musisz albo znak podawać jako znak:

tab[i]!=' ' [/code]

albo podawać kod ASCII znaku:

[code=php]tab[i]!=32

Jeżeli chcesz do końca napisu to:

tab[i]!=0 // lub !='\0' [/code]

(etam) #11

To trochę nie tak. tab[15] to jest piętnasty znak w tablicy tab (mówię tu nie o deklaracji, tylko dalszym użyciu w kodzie).

Do porównywania stringów służy funkcja strcmp.


([alex]) #12

Może nie zauważyłeś ale akurat tu tab[15] jest deklaracją.


(etam) #13

Sorry. Źle zrozumiałem co tam było napisane.

Przy okazji: tablice znaków lepiej deklarować

char tab[]="ala ma kota";

Kompilator sam dobierze odpowiedni rozmiar tablicy (łącznie z miejscem na zero na końcu).


([alex]) #14

Gdyby to było bezwzględnie lepsze to nie było by innej możliwości w C/C++.

Czasami potrzebny jest napis z dodatkowym miejscem na dopisanie czegoś jeszcze.


(Adi Aj) #15

Hmm wiem już jak przeanalizować całą tablicę typy char i tablicę typu int. Wszystko jest podobne. Tylko, że zawsze moje zadanie opierają się na tym by np. przeanalizować tablicę typu char ale za alokowaną dynamicznie.

Mam np. coś takiego:

#include 


int main()

{

  int i, n;

  int pause = 0;

  int znak = 0;  


  char * tab1;

  tab1 = (char *) malloc (n*sizeof(char));


  printf("Podaj wielkosc tablicy: ");

  scanf("%d", &n);

  printf("Zawartosc tablicy: ");

  scanf("c%", &tab1);



  printf("\nWielkosc tablicy: %d \n", n);

  printf("Zawartosc tablicy: %c \n", tab1);

  /*

  char tab[15] = "ala ma kotka.";


  for (i=0; tab[i]!='.' ; i++)

  {

      if (tab[i]!='\n' && tab[i]!=' ' && tab[i]!='\t')

      {

         znak++;                 

      }

      else 

      {

         pause++;

      }


      printf("Wartosc: %c , to jest %d znak, przerwa %d \n", tab[i], znak, pause);      

      //printf("Znaki %d \n", znak);

      //printf("Przerwy %d \n", pause);

  }

 */

  system("PAUSE");	

  return 0;

}

Czytanie całej tablicy ? Nie ma problemu jak widać. Tylko mam problem z wpisaniem wartości np. "ala ma kota." do tej dynamicznie utworzonej tablicy. Wiem, że tablicę dynamiczną można używać jak zwykłej. Jednak mi to nie wychodzi. Podpowiedzcie mi jakiś sposób jednak z wersji prostych, albo pokażcie gdzie mam błąd w moim rozumowaniu :slight_smile:


([alex]) #16
tab1 = (char *) malloc (n*sizeof(char)); // n - nie zainicjalizowano zawiera śmiecie nie wiadomo ile się przydzieliscanf("%d", n); // dopiero teraz określasz n ?scanf("c%", tab1); // wczytujesz znak w młodszą część adresu - jakieś totalne bzdury.for (i=0; tab[i]!='.' ; i++) // nie musisz dawać specjalnego znaku taki już istnieje, lepiej używać ++i niż i++: for(i=0;tab[i];++i) // tak najlepiejif (tab[i]!='\n'  tab[i]!=' '  tab[i]!='\t') // znak nie może być jednocześnie spacja i tabulacją użyj || lub zamiast tego lepiej:if(strchr(" \n\t",tab[i]))[/code]




[code=php]printf("Podaj wielkosc tablicy: ");scanf("%d",n)==1)(n0)) // jeżeli nie to znaczy że użyszkodnik wpisał literki zamiast liczby albo ujemną {tab1=(char*)malloc(n+1); // nie trzeba mnożyć przez sizeof(char) ponieważ zawsze jest 1, +1 na znak końcaprintf("Zawartosc tablicy: ");fgets(tab1,n+1,stdin); // uwaga zawiera '\n' na końcu, jeżeli nie to użyszkodnik wpisał zbyt dużo znakówchar *enter=strchr(tab1,'\n'); // szukamy znak '\n';if(enter) *enter=0; // zamieniamy '\n' na koniec napisuelse printf("podano zbyt duzo znakow\n");