Ebben mi a hiba?


#include <stdio.h>

#define MAXSOR 1000
#define KINT 0
#define BENT 1
#define HOSSZ 20

int gettheline(void);

int clean(int *i);

int length(int *i);

void disphist(int *i);

main()
{
	int *sor;
	int *hossz;
	*sor = gettheline();
	*sor = clean(sor);
	*hossz = length(sor);
	disphist(hossz); 
}

int gettheline(void)
{
	int c, i, sor[MAXSOR];
	i = 0;
	while ( ( i < MAXSOR ) && ( ( c = getchar( ) ) != EOF ) )
		sor[i++] = c;
	sor[i] = '\0';
	return *sor;
}

int clean(int *sor)
{
	int i=0;
	while (sor[i] != '\0')
		if ( ( sor[i] < 'a' ) || ( sor[i] > 'z' ) || ( sor[i] < 'A' ) || ( sor[i] > 'Z' ) ) sor[i++] = ' ';
			else i++;
	return *sor;
}

int length(int *sor)
{
	int hossz[HOSSZ], poz = KINT, szohossz=0;
	int i=0;
	for ( i = 0; i <= HOSSZ; hossz[i++] = 0);
	i = 0;
	while ( sor[i] != '\0' )
	{
		if ( sor[i] != ' ' )
		{
			poz = BENT;
			szohossz++;
		}
		else if ( poz == BENT )
		{
			hossz[szohossz]++;
			poz = KINT;
		}
		i++;
		szohossz = 0;
	}
	return *hossz;
}

void disphist(int *hossz)
{
	int i, j;
	for ( i = 0; i <= 20; i++)
	{
		for ( j = hossz[i]; j > 0; j--)
		{
			printf("*");
		}
		printf("\n");
	}
}

Állandóan szegmentálási hibát jelez, de nem bírok rájönni, miért. Itt a teljes program, egyelőre a gettheline függvényen nem bírok túljutni. (A többi helyen is szeretném kiélvezni a hibakeresés szépségeit, úgyhogy egyelőre azoktól kíméljetek! :) Szeretek szopni. :) )

Hozzászólások

Jó lenne tudni, mennyi a MAXSOR és hol tart az i a szegfóltnál, ill. mekkorára deklaráltad a sort, de első blikkre aszondanám, hogy szépen kiszaladsz a sor területéről.
Ha benne is maradsz, de pont csurig töltöd, és nem marad hely a lezáró NULL-nak (ami ugye van?), aztán a következő sorban kiírsz, az is csúszós útszakasz.

Ugyan teljesen lényegtelen, de éppen 1000. Teljesen mindegy, mert egy üres Ctrl-D-re is segfault. Odáig, hogy lezárjam a tömböt, el sem jutok (egyébként megteszem). És egyszerűen nem bírok rájönni, hogy mi a jó nyavajája van vajon... :(
--
Fight / For The Freedom / Fighting With Steel

'c' valtozo tipusa? Ha char es nem int, lehet gond az EOF ertekkel.

Ez a kod, nekem fordul, es megy...

#include <stdio.h>
#define MAXSOR 1000
int main ()
{
int c;
int i=0;
int sor[MAXSOR];

while ( ( i < MAXSOR ) && ( ( c = getchar() ) != EOF ) )
sor[i++] = c;

return 0;
}

szerk.: Lehet nem ide kellett volna irnom (es igen, ez tulfut :P)

Viszont a kacsacsőrök HTML tag határolók lettek. Próbáld az &lt; és &gt; jelöléseket!

Én egyébként az idevaló kód beszúrásához írtam egy awk scriptet, az minden efféle escape-elést, cserét megcsinál, aztán bemásolom a kódot, s jól jelenik meg.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Hát ez pont abban különbözik, hogy a sor-t a függvényen belül deklarálod, majd a rá mutató pointert adod vissza. Az ilyen változóknak a stacken foglal memóriát a program, és a függvény visszatérése után már nem az lesz ott, amit gondolsz.

Valoszinuleg az i nincs inicializalva es mint tudjuk a c-ben nincs josagos nagymama, aki helyettunk elvegezne, ezert memoriaszemet lehet benne, ami kimutat a MAXSOR-bol.

*hossz = length(sor);
ez nem olyan jo ;) bar az azelotti ket sor sem lol

*sor = gettheline();

Ez mit és hova tárol le? ;)


int *sor;
int *hossz;

*sor = gettheline();

Definiálsz egy pointert, amit inicializálás nélkül dereferenciálsz. Nem kellene a sor-nak értéket adni egyszer?

1) A int gettheline(void) prototípusban a visszatérési érték nem mutató, hanem int.
2) A gettheline törzsében a sor újra van deklarálva, ami elfedi a main-ben deklarált változót.
3) A gettheline függvény a törzsben mutatót ad vissza, de ilyen mutató nem volt deklarálva, a sor ugyanis skalár int-ekből álló tömb a függvényben.
4) Lokális változóra mutatót nem érdemes visszaadni, mert nem garantált, hogy nem lesz felülírva a stack-en, mire a hívóhoz ér.
Nem olvastam tovább, bocs.

Egyfelol, ahogy fent irjak, random memoriateruleteket piszkalni nem szerencses, masfelol a jovore nezve:

[bence@pc1 ~]$ cd /tmp
[bence@pc1 tmp]$ cat <<. >segfault.c
> int
> main(void)
> {
>       int     *b;
>       *b = 5;
>       return 0;
> }
> .
[bence@pc1 tmp]$ cc -g -o segfault segfault.c 
[bence@pc1 tmp]$ gdb ./segfault

	[Jogi blabla..]

Reading symbols from /tmp/segfault...done.
(gdb) run
Starting program: /tmp/segfault 

Program received signal SIGSEGV, Segmentation fault.
0x00000000004004bc in main () at segfault.c:5
5               *b = 5;
(gdb) quit

Igy mondjuk hamar kiderul a turpissag.

--------------------------------------
Unix isn't dead. It just smells funny.

Ha még mindig segfaultol a ciklus végén, akkor én a helyedben teleraknám printf-fel, hogy lásd, hogy valójában mi történik, melyik sornál vagy indexnél száll el (vagy persze debuggerrel is nekimehetsz (pl gdb)).

Viszont nekem a kedvenc részem a kódból, hogy az egyetlen komment ez:
i++; /*Növeljük az indexet*/
:)

Nem bántásból írom, de tipikusan ez az a kommment, ami teljesen felesleges, nem ad hozzá semmit a kódhoz. Ne érts félre, nem azt mondom, hogy tele kell rakni kommenttel, de ha írsz, akkor soha ne arról szóljon, amit egyébként is ki lehet olvasni első ránézésre a kódból, hanem pl ha egy bonyolult feltételt meg kell magyarázni, vagy ha nem egyértelmű, hogy miért csinálja a kód azt, amit csinál. Amúgy nekem a kommentelésről az a véleményem, hogy az a legjobb, ha olyan jól olvasható a kód, hogy nincs szükség kommentre...