Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C ja malloc

Sivun loppuun

Janezki [06.12.2007 21:08:13]

#

Yritän määrittää muutujan "char *subresult" kokoa mallocilla, mutta jostain syystä se asettaa kooksi aina neljä tavua. Ymmärränkö nyt tuon mallocin idean oikein? Jos siis asetan dynaamisen merkkijonon kooksi vaikka 15, niin sinne mahtuu silloin 15 merkkiä.

subresult = (char *)malloc(15);
printf("Reserved size for the absolute result: %i\n", sizeof(subresult));

Tuo alimmainen printtaa aina luvun 4, asetan minkä luvun tahansa mallocin sisälle.

Tarviiko muuten ollenkaan typecastittaa ennen mallocia?

Tässä kohti olisi varmaan hyvä huomauttaa että olen täysi keltanokka c-koodaamisessa.

Megant [06.12.2007 21:23:56]

#

Se kyllä varaa 15 tavua (ja C-tyylisten merkkijonojen kanssa sinne ei mahdu kuin 14 merkkiä + nollatavu), mutta tuo sizeof palauttaa itse muuttujan, eli tässä tapauksessa pointterin koon.
Ja se on nyt se 4 tavua.

Pöytälamppu [06.12.2007 21:25:35]

#

Kyllä se varaa oikean määrän muistia, sizeof palauttaa vain tässä tilanteessa taulukon osoitteen koon (,joka on 32-bittisessä järjestelmässä 4 tavua).

Janezki [06.12.2007 21:36:35]

#

Aha... miten saan palautettua varatun muistin koon?

Markus [06.12.2007 21:46:11]

#

Janezki kirjoitti:

Aha... miten saan palautettua varatun muistin koon?

Et mitenkään, mutta sillähän ei ole mitään väliä, koska sinä jo tiedät varatun muistin määrän. Se on tuo 15 tavua, jonka annat mallocille parametriksi.

Janezki [06.12.2007 22:09:50]

#

Markus kirjoitti:

Janezki kirjoitti:

Aha... miten saan palautettua varatun muistin koon?

Et mitenkään, mutta sillähän ei ole mitään väliä, koska sinä jo tiedät varatun muistin määrän. Se on tuo 15 tavua, jonka annat mallocille parametriksi.

Aa niin tietysti. Tein vain formatointifunktion tuolle merkkijonolle, mutta voihan sen tosiaan parametrinäkin sinnekin toimittaa. Kiitoksia kun taas jaksoitte yhteen (kahteen?) tyhmään kysymykseen vastata.

EDIT: Muuten vielä yksi kysymys pitääkö muisti vapauttaa kun tuolla menetelmällä varaa sitä?

Blaze [06.12.2007 22:42:50]

#

Janezki kirjoitti:

pitääkö muisti vapauttaa kun tuolla menetelmällä varaa sitä?

Tottakai.

Janezki [07.12.2007 08:51:32]

#

Blaze kirjoitti:

Janezki kirjoitti:

pitääkö muisti vapauttaa kun tuolla menetelmällä varaa sitä?

Tottakai.

Entä jos alifunktion palautusarvo on dynaaminen taulukko miten silloin toimitaan? Niin ja miten muisti yleensä vapautetaan taulukoista? Muistakaa että en ole todellakaan koodannut C:llä kovinkaan paljoa.

Janezki [07.12.2007 10:14:35]

#

Muotoilen kysymyksen eri tavalla: Jos määritän funktiossa dynaamisen taulukon ja haluan palauttaa sen funktion arvona, niin missä välissä se tulisi vapauttaa? Esim...

char *funktio()
 {
  char *taulu

  taulu = (char *)malloc(15);

  strcpy(taulu, "098765432109876");

  //Jos vapauttaa tässä niin eihän return pysty enää palauttamaan taulua

  return taulu;

  //Tässä taas funktion suoritus on loppunut?
 }

Blaze [07.12.2007 10:28:23]

#

Janezki kirjoitti:

missä välissä se tulisi vapauttaa?

Sitten kun et enää tarvitse sitä, siis jossain tuon funktion ulkopuolella.

Janezki [07.12.2007 11:15:38]

#

Näin?

char *funktio()
 {
  char *taulu;

  taulu = (char *)malloc(15);

  strcpy(taulu, "098765432109876");

  return taulu;
 }

int main()
 {
  printf("%s\n", funktio);
  free(taulu);          //onko taulu yleensä tässä kohtaa enää olemassa?
  return 0;
 }

Blaze [07.12.2007 11:31:33]

#

Janezki kirjoitti:

onko taulu yleensä tässä kohtaa enää olemassa?

Funktion sisällä määritellyt muuttujat ei näy sen funktion ulkopuolelle.

Näin:

char *funktio()
 {
  char *taulu;
  taulu = (char *)malloc(15);
  strcpy(taulu, "098765432109876");
  return taulu;
 }

int main()
 {
  char* munstringi = funktio();
  printf("%s\n", munstringi);
  free(munstringi);
  return 0;
 }

Janezki [07.12.2007 18:53:17]

#

Blaze kirjoitti:

Funktion sisällä määritellyt muuttujat ei näy sen funktion ulkopuolelle.

Näin:

Voisiko sanoa että munstringi toimii pointterina taululle?

pukki [08.12.2007 13:04:43]

#

Kyllä näin voi sanoa.

Ts.
munstringi == &munstringi[0]

eli munstringi on osoitin sen taulukon ensimmäiseen alkioon.

hunajavohveli [09.12.2007 16:06:40]

#

Janezki kirjoitti:

onko taulu yleensä tässä kohtaa enää olemassa?

Varaamasi muisti toki säilyy niin kauan, kunnes vapautat sen free():llä (tai kunnes ohjelman suoritus päättyy, mutta vapauttaminen kannattaa silti tehdä eksplisiittisesti). Kuten Blazen esimerkissä todetaan, taulu ja munstringi ovat vain osoitinmuuttujia, joihin on talletettu tieto varatun muistialueen alkamiskohdasta, ja niiden näkyvyys noudattaa täysin samoja sääntöjä kuin muidenkin muuttujien näkyvyys. Niitä myös käsitellään kuten muita muuttujia, funktio voi palauttaa muuttujan arvon (return taulu;), arvo voidaan ottaa talteen ja edelleen sijoittaa samantyyppiseen muuttujaan (char* munstringi = funktio();). Jos tuon esimerkin funktio ei palauttaisikaan malloc():lta saatua osoitinta, kyseiseen osoitteeseen ei enää mitenkään päästäisi käsiksi etkä voisi itse enää vapauttaa varaamaasi muistia.

map_ [15.12.2007 22:29:17]

#

Janezki kirjoitti:

Näin?

// ...
  taulu = (char *)malloc(15);

  strcpy(taulu, "098765432109876");
// ...

Muista, että C:ssä merkkijonojen loppuun tulee aina lopetusmerkki ('\0'), kuten Megant ensimmäisessä vastauksessa sivumennen huomautti. Tuossa siis strcpy kirjoittaakin muistialueellesi 16 merkkiä, vaikka olet varannut tilaa vain 15:lle. Se, mitä tuollaisessa tilanteessa tapahtuu ei ole tarkkaan ottaen määriteltyä, koska funktiosi käsittelee muistipaikkaa, joka voi olla jonkin ihan toisen muuttujan käytössä. Virheen nimi on muuten puskuriylivuoto. Käytännössä moiset virheet aiheuttavat todella kummallisia ongelmia, jotka toisinaan ilmenevät vasta paljon myöhemmin ohjelman suorituksen edettyä muihin osiin.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta