Zdar,
jde nějak v C detekovat jestli je proměnná konstanta nebo dynamicky alokovaná?
Mm trošku problém s odalokováním paměti :-/ Když odalokuju konstantu tak to hodí seg fault.
Někdy je proměnná dynamicky alokovaná a někdy má přiřazenou hodnotu z konstanty - defaultní hodnota programu.
Děk za tipy.
[C]Detekce konstanty Vyřešeno
- CZechBoY
- Master Level 9.5
- Příspěvky: 8813
- Registrován: srpen 08
- Bydliště: Brno
- Pohlaví:
- Stav:
Offline
- Kontakt:
[C]Detekce konstanty
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
- MiliNess
- člen BSOD týmu
-
Master Level 9.5
- Příspěvky: 9112
- Registrován: říjen 09
- Bydliště: Cheb
- Pohlaví:
- Stav:
Offline
Re: [C]Detekce konstanty
Asi nemyslíš konstantu, ale automatickou proměnnou na zásobníku, případně statickou proměnnou vs. dynamicky alokovanou proměnnou, ne?
Pokud to potřebuješ zjišťovat, tak to píšeš blbě.
Můžeš sem hodit nějaký konkrétní příklad?
Pokud to potřebuješ zjišťovat, tak to píšeš blbě.
Můžeš sem hodit nějaký konkrétní příklad?
-každý má svou pravdu a ta se nemusí vždycky shodovat s tvou vlastní
-naše problémy jsou pouze v naší hlavě
-okolní svět není ani dobrý ani špatný, je mu zcela lhostejné, jestli existuješ
-nejdůležitější v životě je láska. Všechno ostatní jsou zbytečnosti
-naše problémy jsou pouze v naší hlavě
-okolní svět není ani dobrý ani špatný, je mu zcela lhostejné, jestli existuješ
-nejdůležitější v životě je láska. Všechno ostatní jsou zbytečnosti
- CZechBoY
- Master Level 9.5
- Příspěvky: 8813
- Registrován: srpen 08
- Bydliště: Brno
- Pohlaví:
- Stav:
Offline
- Kontakt:
Re: [C]Detekce konstanty
Konkrétní případ je, že mám aplikaci, která si dává vlastní výchozí hodnoty proměnným, když nejsou zadány přes argument.
Třeba dám projekt.exe -parametr1 -parametr3 tzn když není parametr2 tak si tam dám nějakou hodnotu výchozí.
Jelikož nevim dopředu délku těch parametrů tak si je dynamicky alokuju. K čemu ale dynamicky alokovat místo pro konstantní řetězec, u kterýho vim délku, tedy potřebný počet bajtů v paměti?
Zatím jsem to udělal tak, že alokuju dynamicky i ty konstanty, aby mi to neházelo seg fault u uvolnění paměti.
Třeba dám projekt.exe -parametr1 -parametr3 tzn když není parametr2 tak si tam dám nějakou hodnotu výchozí.
Jelikož nevim dopředu délku těch parametrů tak si je dynamicky alokuju. K čemu ale dynamicky alokovat místo pro konstantní řetězec, u kterýho vim délku, tedy potřebný počet bajtů v paměti?
Zatím jsem to udělal tak, že alokuju dynamicky i ty konstanty, aby mi to neházelo seg fault u uvolnění paměti.
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
Re: [C]Detekce konstanty
A jak ty parametry načítáš? Když máš tohle:
tak dostaneš počet položek a pole řetězců, kde je v [0] název programu a pak případné argumenty jak jdou za sebou. Ty bys po příkazu
měl takový stav:
argc=2
argv[0]="projekt.exe"
argv[1]="-parametr1"
argv[2]="-parametr3"
O délku se starat nemusíš, a o uvolnění také ne, to se udělá automaticky při ukončení programu.
Mimochodem, také jsem viděl tenhle tvar:
Kód: Vybrat vše
int main(int argc, char *argv[])
tak dostaneš počet položek a pole řetězců, kde je v [0] název programu a pak případné argumenty jak jdou za sebou. Ty bys po příkazu
Kód: Vybrat vše
projekt.exe -parametr1 -parametr3
měl takový stav:
argc=2
argv[0]="projekt.exe"
argv[1]="-parametr1"
argv[2]="-parametr3"
O délku se starat nemusíš, a o uvolnění také ne, to se udělá automaticky při ukončení programu.
Mimochodem, také jsem viděl tenhle tvar:
Kód: Vybrat vše
int main(int argc, const char *argv[])
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- CZechBoY
- Master Level 9.5
- Příspěvky: 8813
- Registrován: srpen 08
- Bydliště: Brno
- Pohlaví:
- Stav:
Offline
- Kontakt:
Re: [C]Detekce konstanty
Na novej tvar to já kašlu, připadá mi to stejný.
Nezajmá mě co je v parametrech, to je pro ilustraci, abyste pochopili můj problém... tzn. dosazení výchozí hodnoty když parametr chybí.
Nezajmá mě co je v parametrech, to je pro ilustraci, abyste pochopili můj problém... tzn. dosazení výchozí hodnoty když parametr chybí.
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
- MiliNess
- člen BSOD týmu
-
Master Level 9.5
- Příspěvky: 9112
- Registrován: říjen 09
- Bydliště: Cheb
- Pohlaví:
- Stav:
Offline
Re: [C]Detekce konstanty
Já to ale nechápu. V Céčku už pár let programuju, nikdy jsem ale nepotřeboval řešit to, co ty.
Musel bys funkci free() umístit do bloku __try, v handleru __except pak vyjímku zachytit a vyřešit.
To platí pro Windows, pro Linux je to trochu jinak.
Musel bys funkci free() umístit do bloku __try, v handleru __except pak vyjímku zachytit a vyřešit.
To platí pro Windows, pro Linux je to trochu jinak.
-každý má svou pravdu a ta se nemusí vždycky shodovat s tvou vlastní
-naše problémy jsou pouze v naší hlavě
-okolní svět není ani dobrý ani špatný, je mu zcela lhostejné, jestli existuješ
-nejdůležitější v životě je láska. Všechno ostatní jsou zbytečnosti
-naše problémy jsou pouze v naší hlavě
-okolní svět není ani dobrý ani špatný, je mu zcela lhostejné, jestli existuješ
-nejdůležitější v životě je láska. Všechno ostatní jsou zbytečnosti
Re: [C]Detekce konstanty
To není nový tvar, ale docela šikovná věc. Tím modifikátorem const totiž překladači něco sděluješ...
Pořád mi ale není jasné co máš za problém. Program prostě dostane seznam argumentů a ty si musí sám rozebrat. Při tom, pokud nějaký očekávaný není na seznamu, dosadí defaultní hodnotu. Ten seznam také může být prázdný, pak ji dosadí do všech.
Asi bude lepší sem pro ilustraci hodit nějaký jednoduchý prográmek, aby bylo jasné co přesně děláš.
Pořád mi ale není jasné co máš za problém. Program prostě dostane seznam argumentů a ty si musí sám rozebrat. Při tom, pokud nějaký očekávaný není na seznamu, dosadí defaultní hodnotu. Ten seznam také může být prázdný, pak ji dosadí do všech.
Asi bude lepší sem pro ilustraci hodit nějaký jednoduchý prográmek, aby bylo jasné co přesně děláš.
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- CZechBoY
- Master Level 9.5
- Příspěvky: 8813
- Registrován: srpen 08
- Bydliště: Brno
- Pohlaví:
- Stav:
Offline
- Kontakt:
Re: [C]Detekce konstanty
Jáj, pořád nevim co nechápete 
Ukázku zkusim teda no ...
Třeba takhle, akorát neberu hodnoty přímo z args, ale ještě rozřežu ten arg na více částí a potom ty části ukládám do struktury.

Ukázku zkusim teda no ...

Kód: Vybrat vše
#define DEFAULT_CHAR1 "nazdar"
#define DEFAULT_CHAR2 "cojee"
// parsuje parametry...
int parseParams(char** args) {
struktura params {char1; char2; char3};
if (args[1] == "-char2") {
params.char1 = DEFAULT_CHAR1;
params.char2 = DEFAULT_CHAR2;
} else {
params.char1 = (char*)malloc(strlen(args[2]));
if (params.char1 == NULL) {epic fail}
strcpy(params.char1, args[2]);
}
}
Třeba takhle, akorát neberu hodnoty přímo z args, ale ještě rozřežu ten arg na více částí a potom ty části ukládám do struktury.
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
- MiliNess
- člen BSOD týmu
-
Master Level 9.5
- Příspěvky: 9112
- Registrován: říjen 09
- Bydliště: Cheb
- Pohlaví:
- Stav:
Offline
Re: [C]Detekce konstanty
Takový problém musíš řešit proto, že ta konstrukce není moc šťastná.
Prostě buď použij strukturu
a paměť alokuj jak v případě, že budeš používat defaultní paramert, tak v případě, že budeš kopírovat paramert z command line bufferu
nebo použij takovou strukturu
Nemusíš nic dynamicky alokovat a délka parametru bude těžko více jak 999 znaků. Pro jistotu si délku můžeš ošetřit.
Osobně v takových situacích vůbec paměť dynamicky nealokuji, protože se alokace může posrat. Čím je to jednodušší,
tím méně míst, kde může vzniknout chyba. Navíc můžeš zapomenout uvolnit paměť.
Prostě buď použij strukturu
Kód: Vybrat vše
struct params
{
char * char1;
char * char2;
char * char3;
};
a paměť alokuj jak v případě, že budeš používat defaultní paramert, tak v případě, že budeš kopírovat paramert z command line bufferu
nebo použij takovou strukturu
Kód: Vybrat vše
struct params
{
char char1[1000];
char char2[1000];
char char3[1000];
};
Nemusíš nic dynamicky alokovat a délka parametru bude těžko více jak 999 znaků. Pro jistotu si délku můžeš ošetřit.
Osobně v takových situacích vůbec paměť dynamicky nealokuji, protože se alokace může posrat. Čím je to jednodušší,
tím méně míst, kde může vzniknout chyba. Navíc můžeš zapomenout uvolnit paměť.
-každý má svou pravdu a ta se nemusí vždycky shodovat s tvou vlastní
-naše problémy jsou pouze v naší hlavě
-okolní svět není ani dobrý ani špatný, je mu zcela lhostejné, jestli existuješ
-nejdůležitější v životě je láska. Všechno ostatní jsou zbytečnosti
-naše problémy jsou pouze v naší hlavě
-okolní svět není ani dobrý ani špatný, je mu zcela lhostejné, jestli existuješ
-nejdůležitější v životě je láska. Všechno ostatní jsou zbytečnosti
Re: [C]Detekce konstanty
Chybička se vloudila, správně to včera mělo být takhle:
argc=3 !!!
argv[0]="projekt.exe"
argv[1]="-parametr1"
argv[2]="-parametr3"
Ano, je to sice k neuvěření, ale v Céčku pole začínají od nuly, a řetězce se opravdu porovnávat pomocí == nedají (tohle není BASIC), takže jsem ten tvůj program trochu (spíš totálně) překopal a zprovoznil:
V té funkci nemůžeš testovat args[2], protože nevíš jestli tam nějaký další je! Musel bys předávat i argc.
Porovnávat řetězce se dá jedině pomocí funkce strcmp(), kopírovat pomocí strcpy().
Strukturu je lepší deklarovat jako vlastní typ, lépe se pak s ní pracuje, bez toho musíš všude psát struct proměnná.
argc=3 !!!
argv[0]="projekt.exe"
argv[1]="-parametr1"
argv[2]="-parametr3"
Ano, je to sice k neuvěření, ale v Céčku pole začínají od nuly, a řetězce se opravdu porovnávat pomocí == nedají (tohle není BASIC), takže jsem ten tvůj program trochu (spíš totálně) překopal a zprovoznil:
Kód: Vybrat vše
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_CHAR1 "nazdar"
#define DEFAULT_CHAR2 "cojee"
typedef struct {
char *char1;
char *char2;
char *char3;
} ARGS;
/* parsuje parametry... */
int parseParams(char **args)
{
ARGS params;
if (!strcmp(args[1],"-char2"))
{
params.char1 = DEFAULT_CHAR1;
params.char2 = DEFAULT_CHAR2;
printf("Zkopírovány konstanty:\n%s\n%s\n",params.char1,params.char2);
}
else
{
if ((params.char1 = (char*)malloc(strlen(args[1]))))
{
/* process */
strcpy(params.char1,args[1]);
printf("Úspěšně naalokováno a zkopírováno:\n%s\n",params.char1);
free(params.char1);
}
else
{
/* epic fail */
fprintf(stderr,"ERROR alokace!\n");
}
}
return 0;
}
int main(int argc,char *argv[])
{
int i;
/* nejdřív výpis všech argumentů pro kontrolu */
printf("argc:\t%d\n",argc);
for (i=0;i<argc;++i)
{
printf("%d:\t%s\n",i,argv[i]);
}
/* a pokud byly nějaké zadány, zavoláme funkci */
if (argc>1)
{
parseParams(argv);
}
else
{
fprintf(stderr,"Nemám žádné parametry!\n!");
}
return 0;
}
V té funkci nemůžeš testovat args[2], protože nevíš jestli tam nějaký další je! Musel bys předávat i argc.
Porovnávat řetězce se dá jedině pomocí funkce strcmp(), kopírovat pomocí strcpy().
Strukturu je lepší deklarovat jako vlastní typ, lépe se pak s ní pracuje, bez toho musíš všude psát struct proměnná.
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- CZechBoY
- Master Level 9.5
- Příspěvky: 8813
- Registrován: srpen 08
- Bydliště: Brno
- Pohlaví:
- Stav:
Offline
- Kontakt:
Re: [C]Detekce konstanty
Jo, chápu že stringy nemůžou porovnávat přes ==, já íšou většinou v pseudokodu 
Tisícovej buffer fakt nechci používat, však to žere 1kB paměti ať tam nacpu 2 znaky nebo 1000 ne?
faraon: Takže když dám strcpy tak nemusim alokovat paměť? To je super, ale už jsem projekt odevzdal
Jak já se s**l s tim alokováním a nultejma bajtama na konci

Tisícovej buffer fakt nechci používat, však to žere 1kB paměti ať tam nacpu 2 znaky nebo 1000 ne?
faraon: Takže když dám strcpy tak nemusim alokovat paměť? To je super, ale už jsem projekt odevzdal

Jak já se s**l s tim alokováním a nultejma bajtama na konci

PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
Re: [C]Detekce konstanty
Alokovat jí musíš, ale jen tolik kolik je potřeba. A to strcpy() tam zkopíruje i ten nulový znak na konci. Teď mě napadá že to asi mělo být spíš
if ((params.char1 = (char*)malloc(strlen(args[1])+1)))
Tak to dopadá když si člověk neidělá všechno sám
Na strcpy() bacha, protože to kopíruje až do '\0', pokud ho tam nemáš, jede dokud ho nenajde, což může být docela dlouho... Někdy i do segfaultu!
To se tady nemůže stát, protože ten řetězec už je (měl by být) zkontrolovaný, tak můžeš použít rychlejší funkci.
Pak je také strncpy(), kterému zadáš i kolik bajtů maximálně smí zkopírovat, aby nedošlo k přetečení.
Můj pseudokód by vypadal spíš takhle nějak:
if equal(string1,string2)...
Alokování je fajn věc, akorát se musí vždy kontrolovat návratová hodnota. Ale větší zábava je s uvolňováním, aby ti program nežral paměť jako Firefox
Ještě mě napadla jedna věc, teoreticky by konstanta měla být uložená v jiném bloku paměti než ta tvoje alokace, takže by stačilo porovnat pár ukazatelů. Ale záleží na druhu a na tom kdy vznikla, navíc není jisté co s tím překladač při optimalizaci a operační systém při spouštění provedou, asi by to nebylo spolehlivé.
if ((params.char1 = (char*)malloc(strlen(args[1])+1)))
Tak to dopadá když si člověk neidělá všechno sám

Na strcpy() bacha, protože to kopíruje až do '\0', pokud ho tam nemáš, jede dokud ho nenajde, což může být docela dlouho... Někdy i do segfaultu!
To se tady nemůže stát, protože ten řetězec už je (měl by být) zkontrolovaný, tak můžeš použít rychlejší funkci.
Pak je také strncpy(), kterému zadáš i kolik bajtů maximálně smí zkopírovat, aby nedošlo k přetečení.
Můj pseudokód by vypadal spíš takhle nějak:
if equal(string1,string2)...
Alokování je fajn věc, akorát se musí vždy kontrolovat návratová hodnota. Ale větší zábava je s uvolňováním, aby ti program nežral paměť jako Firefox

Ještě mě napadla jedna věc, teoreticky by konstanta měla být uložená v jiném bloku paměti než ta tvoje alokace, takže by stačilo porovnat pár ukazatelů. Ale záleží na druhu a na tom kdy vznikla, navíc není jisté co s tím překladač při optimalizaci a operační systém při spouštění provedou, asi by to nebylo spolehlivé.
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
Zpět na “Programování a tvorba webu”
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti