Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.
Vaše pomoc je stále potřeba!

Autor Téma: Céčkový program padá se SIGSEGV [vyřešeno]  (Přečteno 3884 krát)

Royal

  • Návštěvník
  • Příspěvků: 31
Céčkový program padá se SIGSEGV [vyřešeno]
« kdy: 28 Února 2011, 11:21:07 »
Buďte zdrávi,

nevím, jestli toto spadá pod tuto kategorii, a celkově i pod toto fórum, ale mám problém s C.
Mám následující kód:

Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>
char *str;
int main()
{
    printf("Napis neco:\t");
    scanf("%s", &str);
    printf("Zadal jsi '%s'.\n", str);
    return 0;
}

Program zkompiluju s varováním "scanf.c:9: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’", nicméně zkompiluju.
Spustím ho, něco napíšu, enter a "Neoprávněný přístup do paměti (SIGSEGV)".

Už jsem zkoušel zaměnit "char *str;" za "char *str = malloc(sizeof(char)*30);", ale GCC hlásí chybu.
Taky jsem zkoušel dát na začátek funkce main() "str = malloc(sizeof(char)*30);", ale jako by to tam nebylo, pořád to padá.
Taky musím mít proměnnou str deklarovanou před začátkem funkce main, protože ve složitějším programu, který píšu, využívají tuto proměnnou ještě další funkce.

Co mám do toho kódu ještě napsat nebo co mám změnit, aby to fungovalo, prosím?
Díky
« Poslední změna: 28 Února 2011, 11:55:49 od Royal »

premet

  • Host
Re: Céčkový program padá se SIGSEGV
« Odpověď #1 kdy: 28 Února 2011, 11:41:27 »
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

int main()
{
   
    char *str = (char*) malloc(30 * sizeof(char));
 
    printf("Napis neco:\t");
    scanf("%s", str);
    printf("Zadal jsi '%s'.\n", str);
    return 0;
}

1) char * str máš už ukazatel a scanf chce adresu, proto ti to hlásí chybu
2) pokud to chceš použít takhle, musíš mít pamět alokovanou což ti u globální proměnné nepůjde, musel by si mít char str[30] třeba
3) pokud píšeš složitější program a neporadíš si s tímhle, tak bych začal psát jednodušší

Royal

  • Návštěvník
  • Příspěvků: 31
Re: Céčkový program padá se SIGSEGV
« Odpověď #2 kdy: 28 Února 2011, 11:55:19 »
Nenapadlo mě, že by scanf chtěl adresu... Díky. Teď už to vím a pro příště se poučím.

Pomohlo mi definovat proměnnou char str2[30], jejíž hodnotu jsem potom přiřadil globální proměnné char *str. Myslím si sice, že to není moc elegantní řešení (možná i trochu prasácké), ale prozatím funguje, přestože GCC hlásí varování.

Když jsem ten program začínal psát, měl jsem tam vstupní proměnnou pevně definovanou, protože jsem znal správný výstup. Zadávání vstupu uživatelem jsem přidal až jako poslední věc, a nenapadlo mě, že by s tím byl tak velký problém. Neměl jsem páru o tom, jak scanf funguje.

P.S. Možná máme jiný názor na to, co je "složitější" a "jednodušší" program.
Jsem v C relativní začátečník. Dřív jsem psal v C# (a to bylo ještě na Win), který je v těchto věcech jednodušší.

Znovu děkuji. Program je hotový.

Šuohob

  • Závislák
  • ***
  • Příspěvků: 2171
Re: Céčkový program padá se SIGSEGV
« Odpověď #3 kdy: 28 Února 2011, 11:57:01 »
4. globalni promenna je v C prasarna, udelej ji lokalni v main a predavej ji pomoci parametru funkce
Tak dlouho se vrzá s Acerem, až se displej utrhne.

premet

  • Host
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #4 kdy: 28 Února 2011, 12:00:04 »
Pomohlo mi definovat proměnnou char str2[30], jejíž hodnotu jsem potom přiřadil globální proměnné char *str. Myslím si sice, že to není moc elegantní řešení (možná i trochu prasácké), ale prozatím funguje, přestože GCC hlásí varování.
Proč je potřeba něčeho takovýho  ???

Royal

  • Návštěvník
  • Příspěvků: 31
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #5 kdy: 28 Února 2011, 12:04:59 »
4. globalni promenna je v C prasarna, udelej ji lokalni v main a predavej ji pomoci parametru funkce

To mě ani nenapadlo :o
Ale jak to mám udělat, pokud chci do té proměnné zapisovat z více funkcí?


Proč je potřeba něčeho takovýho  ???

Nevím, jak to mám lépe udělat :(

mka

  • Závislák
  • ***
  • Příspěvků: 1907
  • Chybovat je moje.
    • Příložany Cé Zet
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #6 kdy: 28 Února 2011, 12:13:39 »
Předně si ujasni používání pointerů. To je naprostej základ.
Dále: když už použiješ nějaké strx[y], tak proč už ne rovnou tu "primární" str? tedy třeba char str[256]. Vyhraď si raději více místa, protože pokud někdo zadá delší řetězec, než máš vyhrazenou paměť, je z toho průser.
Nicméně i přesto si ji raději deklaruj v těle main.

Royal

  • Návštěvník
  • Příspěvků: 31
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #7 kdy: 28 Února 2011, 12:17:21 »
Předně si ujasni používání pointerů. To je naprostej základ.
Dále: když už použiješ nějaké strx[y], tak proč už ne rovnou tu "primární" str? tedy třeba char str[256]. Vyhraď si raději více místa, protože pokud někdo zadá delší řetězec, než máš vyhrazenou paměť, je z toho průser.
Nicméně i přesto si ji raději deklaruj v těle main.

Tak kde mám používat pointery? Pořád mi není jasné, k čemu jsou.
Globální *str vyměním za str[X].
Když někdo zadá delší řetězec, tak se prostě ta část, která přesahuje, neuloží, ne? Na konci bude pořád nullbajt.
Co si mám deklarovat v main()?

MacHala

  • Stálý člen
  • **
  • Příspěvků: 1104
  • Big Bro iz watching joo!
    • ZlejT
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #8 kdy: 28 Února 2011, 12:36:59 »
Globální *str vyměním za str[X].
Když někdo zadá delší řetězec, tak se prostě ta část, která přesahuje, neuloží, ne? Na konci bude pořád nullbajt.
opravdu si precti neco o C a idealne i o asembleru abys pochopil jak to funguje - kdyz do pole zapises vetsi pocet bytu, nez ma kapacitu, tak to pretece a bud si prepises dalsi globalni data, nebo budes zapisovat uz mimo pamet vyhrazenou pro tvuj program a kernel ti to zatrhne (SIGSEGV)

Tak kde mám používat pointery? Pořád mi není jasné, k čemu jsou.
ukazatel je adresa do pameti - kdyz tam je hvezdicka, pracujes s daty na te adrese, kdyz tam hvezdicka neni, pracujes s adresou samotnou - polopaticteji uz to rict asi nejde
Prislusnik ligy, za kreativni pouzivani interpunkcnich znamenek, carek, predevsim.
=======================================
Tweetuju jako http://twitter.com/zl8

Royal

  • Návštěvník
  • Příspěvků: 31
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #9 kdy: 28 Února 2011, 12:41:22 »
ukazatel je adresa do pameti - kdyz tam je hvezdicka, pracujes s daty na te adrese, kdyz tam hvezdicka neni, pracujes s adresou samotnou - polopaticteji uz to rict asi nejde

To chápu. Ale kdy mám použít ukazatel a ne?

O C si určitě něco přečtu. Teď toho vím sice víc, ale také víc věcí nechápu a stále vím, že nic nevím.

mka

  • Závislák
  • ***
  • Příspěvků: 1907
  • Chybovat je moje.
    • Příložany Cé Zet
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #10 kdy: 28 Února 2011, 13:08:10 »
Začít můžeš třeba tady: http://www.linuxsoft.cz/article_list.php?id_kategory=186.
Dokud nebudeš mít jasno v zápisech typu char, *char, char[], *char[], **char a podobně, budeš to mít těžké.

Něco podobného, s čím se tady trápíš, se řeší zde: http://www.linuxsoft.cz/article.php?id_article=578.
Čti a zkoušej si to pořád dokola, dokud to nepochopíš. Hodně štěstí.

Royal

  • Návštěvník
  • Příspěvků: 31
Re: Céčkový program padá se SIGSEGV [vyřešeno]
« Odpověď #11 kdy: 28 Února 2011, 13:11:52 »
Začít můžeš třeba tady: http://www.linuxsoft.cz/article_list.php?id_kategory=186.
Dokud nebudeš mít jasno v zápisech typu char, *char, char[], *char[], **char a podobně, budeš to mít těžké.

Něco podobného, s čím se tady trápíš, se řeší zde: http://www.linuxsoft.cz/article.php?id_article=578.
Čti a zkoušej si to pořád dokola, dokud to nepochopíš. Hodně štěstí.

No... Díky. Proberu se tím.

 

Provoz zaštiťuje spolek OpenAlt.