Portál AbcLinuxu, 9. května 2025 02:59

Dotaz: C ukazatel přetečení zásobníku

4.1.2014 23:05 kammtar
C ukazatel přetečení zásobníku
Přečteno: 642×
Odpovědět | Admin
Zdravím, Narazil jsme na jednu věc a docela by mě zajímalo proč.

char *buff; getcwd(buff,100);

Vyzkoušel jsem tento kód funguje správně ale v momentě kdy se snažím do programu přidat byť i jenom jeden int tak to skončí na SIGSEV.

Vím že za použití malloc je problém vyřešen ale mě zajímá proč. Aji když si getcwd alokuje něco kolem 100*sizeof(char) tak to nemůže zaplnit celý zásobník ne? Dále v programu už používám jenom opendir() který mi snad nehází ty data na zásobník.
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

4.1.2014 23:18 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Odpovědět | | Sbalit | Link | Blokovat | Admin
char *buff je jen neinicializovaný (ukazující kdokoliv ví kam), nealokuje žádnou paměť.

To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
4.1.2014 23:19 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Oprava:
char *buff je jen neinicializovaný ukazatel/pointer (ukazující kdokoliv ví kam), nealokuješ žádnou paměť.
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
4.1.2014 23:25 kammtar
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
To je mi jasné, ale proč to pokaždé funguje? Podle manuálu getcwd() si alokuje paměť když je pointer na buffer null což není.
4.1.2014 23:29 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
C-čko tě nekontroluje co děláš, nikdo nic nealokuje, prostě to píše na tu velmi-velmi-pseudo náhodnou adresu kam to ukazuje.
Nedal;s NULL, a řekl's že na té adrese je 100 char-ů alokovaných, tak se to tam zapíše.
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
martin-ux avatar 5.1.2014 00:11 martin-ux | skóre: 18 | Bratislava
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
nie je tak pravda .. getcwd ho alokuje, ked je NULL. az teraz som pochopil, co sa OP pyta.

takto je to ok:
int main() {
	char* buf = NULL;
	buf = getcwd(buf, 100);

	printf ("buf: %s\n", buf);

	free(buf);
	buf = NULL;

	return 0;
}
buf musi byt NULL aby sa alokoval novy space. ak je not NULL, tak getcwd() to bere ako pointer na alokovany space.

src: FreeBSD: /usr/src/lib/libc/gen/getcwd.c:

    90		} else {
    91			if ((pt = malloc(ptsize = PATH_MAX)) == NULL)
    92				return (NULL);
    93			ept = pt + ptsize;
kde pt je prvy arg. fcie.
..when you do things right, people won't be sure you've done anything at all..
5.1.2014 16:20 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Ano, tak to je. A co není pravda?
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
martin-ux avatar 5.1.2014 16:51 martin-ux | skóre: 18 | Bratislava
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
nedaju sa editovat prispevky, chcel som napisat "nie je to tak celkom pravda". tym som chcel reagovat na:
nikdo nic nealokuje
ze v tomto pripade getcwd() alokuje za neho buffer, ak je vstupny argument pre buf NULL.
..when you do things right, people won't be sure you've done anything at all..
5.1.2014 17:09 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Ju, už mi to pomalu došlo, to je jen nedorozumění.
»nikdo nic nealokuje« jsem myslel v tom původním případě, tedy tehdy pokud není ukazatel inicializovaný (na NULL nebo na alokovanou paměť).
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
martin-ux avatar 5.1.2014 19:31 martin-ux | skóre: 18 | Bratislava
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
jj, sme sa nerozumeli :).
..when you do things right, people won't be sure you've done anything at all..
4.1.2014 23:30 majkl
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
protoze nahoda? pustit to treba jindy/jinde, zas to pokazdy zhavaruje
martin-ux avatar 4.1.2014 23:55 martin-ux | skóre: 18 | Bratislava
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Odpovědět | | Sbalit | Link | Blokovat | Admin
velmi vela, hodne dobrych FAQs na jednom mieste aj s vysvetlenim tu, tvoj problem tu
..when you do things right, people won't be sure you've done anything at all..
5.1.2014 10:57 potato
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Odpovědět | | Sbalit | Link | Blokovat | Admin
Kód nefunguje správně. S tvou verzí kompilátoru, architekturou, volbami při kompilaci, ..., etc. se náhodou předá getcwd() vhodný první argument.

Proměnné na zásobníku jsou neinicializovaná. Když je neinicializovaný buff náhodou NULL, tak getcwd() alokuje paměť. To je ten případ, kdy si myslíš, že to funguje.

Když něco přidáš, tak to dopadne tak (opět náhodou), že neinicializovaný buff už není NULL -- a getcwd() tedy dostane ukazatel někam doprčic a program spadne.
5.1.2014 19:11 Program
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Odpovědět | | Sbalit | Link | Blokovat | Admin
Ač trochu nesrozumitelně, ale už byla asi většina věcí vysvětlená. Jen bych trochu upřesnil, že ačkoli getpwd při NULL pointeru inteligentně alokuje pamět, nealokuje ji na zásobníku, ale na haldě, takže se vždy musí uvolnit pomocí free, jinak vzniká tzv. memory leak. Nastudujte si, jak to funguje, jinak nic v C nenaprogramujete (všechno bude dřív nebo později padat)
14.1.2014 17:16 Nikola Pajkovský | skóre: 16
Rozbalit Rozbalit vše Re: C ukazatel přetečení zásobníku
Odpovědět | | Sbalit | Link | Blokovat | Admin

As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc) getcwd() allocates the buffer dynamically using malloc(3) if buf is NULL. In this case, the allocated buffer has the length size unless size is zero, when buf is allocated as big as necessary. The caller should free(3) the returned buffer.

#include <linux/limits.h>

/* ... includes ...*/

char *buf = NULL;
buf = getcwd(buf, PATH_MAX);
nebo
#include <linux/limits.h>

/* ... includes ...*/

char buf[PATH_MAX];
buf = getwd(buf, sizeof(buf));
Save the whales. Feed the hungry. Free the mallocs

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.