[C]Detekce konstanty Vyřešeno

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

[C]Detekce konstanty

Příspěvekod CZechBoY » 20 bře 2014 14:27

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.
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

Reklama
Uživatelský avatar
MiliNess
člen BSOD týmu
Master Level 9.5
Master Level 9.5
Příspěvky: 9112
Registrován: říjen 09
Bydliště: Cheb
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod MiliNess » 20 bře 2014 15:10

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?
-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

Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: [C]Detekce konstanty

Příspěvekod CZechBoY » 20 bře 2014 16:00

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.
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

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod faraon » 20 bře 2014 16:52

A jak ty parametry načítáš? Když máš tohle:

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)

Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: [C]Detekce konstanty

Příspěvekod CZechBoY » 20 bře 2014 16:54

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í.
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

Uživatelský avatar
MiliNess
člen BSOD týmu
Master Level 9.5
Master Level 9.5
Příspěvky: 9112
Registrován: říjen 09
Bydliště: Cheb
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod MiliNess » 20 bře 2014 18:11

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.
-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

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod faraon » 21 bře 2014 05:29

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áš.
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)

Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: [C]Detekce konstanty

Příspěvekod CZechBoY » 21 bře 2014 10:05

Jáj, pořád nevim co nechápete :D
Ukázku zkusim teda no ... :idea:

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

Uživatelský avatar
MiliNess
člen BSOD týmu
Master Level 9.5
Master Level 9.5
Příspěvky: 9112
Registrován: říjen 09
Bydliště: Cheb
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod MiliNess » 21 bře 2014 11:19

Takový problém musíš řešit proto, že ta konstrukce není moc šťastná.
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

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod faraon » 21 bře 2014 20:47

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:

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)

Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: [C]Detekce konstanty

Příspěvekod CZechBoY » 24 bře 2014 00:01

Jo, chápu že stringy nemůžou porovnávat přes ==, já íšou většinou v pseudokodu :D
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 :D
Jak já se s**l s tim alokováním a nultejma bajtama na konci :roll:
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

Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7397
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: [C]Detekce konstanty

Příspěvekod faraon » 24 bře 2014 05:37

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 :lol:

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)


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 8 hostů