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.
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.
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).
Aha... miten saan palautettua varatun muistin koon?
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.
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ä?
Janezki kirjoitti:
pitääkö muisti vapauttaa kun tuolla menetelmällä varaa sitä?
Tottakai.
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.
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? }
Janezki kirjoitti:
missä välissä se tulisi vapauttaa?
Sitten kun et enää tarvitse sitä, siis jossain tuon funktion ulkopuolella.
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; }
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; }
Blaze kirjoitti:
Funktion sisällä määritellyt muuttujat ei näy sen funktion ulkopuolelle.
Näin:
Voisiko sanoa että munstringi toimii pointterina taululle?
Kyllä näin voi sanoa.
Ts.
munstringi == &munstringi[0]
eli munstringi on osoitin sen taulukon ensimmäiseen alkioon.
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.
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.