[x] Segmentation fault und Großes Fragezeichen in Bezug auf malloc

Post Reply
Message
Author
User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

[x] Segmentation fault und Großes Fragezeichen in Bezug auf malloc

#1 Post by Lateralus »

Das folgende Programm löst in der mit "NOTE" markierten Zeile einen Speicherzugriffsfehler aus. Ich wüsste gerne, warum.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int readwordlist&#40;char **wordarray, char *listfilename&#41;;

/* start main */
int main&#40;int argc, char **argv&#41;
&#123;
	/* char *prog=argv&#91;0&#93;; */
	char *wordlist=argv&#91;1&#93;;

	int wordnumber;
	char **words;

	wordnumber=readwordlist&#40;words, wordlist&#41;;
	fprintf&#40;stdout, "Es wurden %d Woerter eingelesen.\n", wordnumber&#41;;

	return 0;
&#125;
/* end main */

int readwordlist&#40;char **wordarray, char *listfilename&#41;
&#123;
	FILE *fp;
	char c;
	char buf&#91;100&#93;; /* Maximale Wortlaenge */
	int index=0;
	int number=0; /* Die Anzahl der eingelesenen Woerter */

	if&#40;&#40;fp=fopen&#40;listfilename, "r"&#41;&#41; == NULL&#41;
	&#123;
		fprintf&#40;stderr, "Wortliste %s konnte nicht gelesen werden.\n", listfilename&#41;;
		exit&#40;5&#41;;
	&#125;
	
	/*TODO&#58; Vielleicht mit Zeigern arbeiten */

	while&#40;&#40;c=getc&#40;fp&#41;&#41; != EOF&#41;
	&#123;
		if&#40;index == 100&#41;
		&#123;
			fprintf&#40;stderr, "Wortliste %s enthaellt zu langes Wort.\n", listfilename&#41;;
			exit&#40;6&#41;;
		&#125;

		if&#40; &#40;c == ' ' || c == '\t' || c == '\n'&#41; && index > 0&#41;
		&#123;
			buf&#91;index&#93;='\0';

			/* Speicher freigeben und puffer in *wordarray kopieren */
			if&#40;&#40; wordarray=malloc&#40;&#40;index+1&#41;*sizeof&#40;char&#41;&#41; &#41; == NULL&#41;
			&#123;
				fprintf&#40;stderr, "Speicher konnte nicht freigegeben werden.\n"&#41;;
				exit&#40;8&#41;;
			&#125;
			
			/* FUNKTIONIERT&#58; *wordarray="TEST"; */
			fprintf&#40;stdout, "In buf liegt&#58; \"%s\".\n", buf&#41;;
			fprintf&#40;stdout, "Index=%d.\n", index&#41;;

			fprintf&#40;stdout, "**wordarray hat die Groesse %d.\n", sizeof&#40;**wordarray&#41;&#41;;
			fprintf&#40;stdout, "*wordarray hat die Groesse %d.\n", sizeof&#40;*wordarray&#41;&#41;;
			fprintf&#40;stdout, "wordarray hat die Groesse %d.\n", sizeof&#40;wordarray&#41;&#41;;

/* NOTE&#58; LOEST SEGMENTATION FAULT AUS&#58; */ strncpy&#40;*wordarray, buf, index+1&#41;;

			wordarray++;
			number++;
			index=0;
		&#125;
		else
		&#123;
			buf&#91;index&#93;=c;
			index++;
		&#125;

	&#125;

	fclose&#40;fp&#41;;

	if&#40;number == 0&#41;
	&#123;
		fprintf&#40;stderr, "Es konnte kein Wort aus %s eingelesen werden. Datei leer?\n", listfilename&#41;;
		exit&#40;7&#41;;
	&#125;

	return number;
&#125;

Außerdem verstehe ich die Ausgabe dieser Zeilen nicht:

Code: Select all

         fprintf&#40;stdout, "**wordarray hat die Groesse %d.\n", sizeof&#40;**wordarray&#41;&#41;; 
         fprintf&#40;stdout, "*wordarray hat die Groesse %d.\n", sizeof&#40;*wordarray&#41;&#41;; 
         fprintf&#40;stdout, "wordarray hat die Groesse %d.\n", sizeof&#40;wordarray&#41;&#41;;
Welche bei mir immer

**wordarray hat die Groesse 1.
*wordarray hat die Groesse 4.
wordarray hat die Groesse 4.

ist. (also **wordarray ist klar, weil's halt char ist.)

Befehle wie " **wordarray='t'; " brechen ebenfalls mit einem seg fault ab.
Last edited by Lateralus on 16. Mar 2005 13:25, edited 1 time in total.

User avatar
heinrich
Posts: 219
Joined: 22. Sep 1999 11:22
Location: N49.137 E8.544

Re: Segmentation fault und Großes Fragezeichen in Bezug auf malloc

#2 Post by heinrich »

Ich drehe mal die Fragen rum, weil ich für deine erste Frage mehr Platz brauche...
Lateralus wrote:Außerdem verstehe ich die Ausgabe dieser Zeilen nicht:

Code: Select all

         fprintf&#40;stdout, "**wordarray hat die Groesse %d.\n", sizeof&#40;**wordarray&#41;&#41;; 
         fprintf&#40;stdout, "*wordarray hat die Groesse %d.\n", sizeof&#40;*wordarray&#41;&#41;; 
         fprintf&#40;stdout, "wordarray hat die Groesse %d.\n", sizeof&#40;wordarray&#41;&#41;;
Welche bei mir immer

**wordarray hat die Groesse 1.
*wordarray hat die Groesse 4.
wordarray hat die Groesse 4.

ist. (also **wordarray ist klar, weil's halt char ist.)
wordarray und *wordarray sind beides Zeiger (Datentyp: char* bzw. char**) wohingegen **wordarray lediglich vom Datentyp char ist.

Und jetzt zu deinem eigentlichen Problem...
Lateralus wrote:Das folgende Programm löst in der mit "NOTE" markierten Zeile einen Speicherzugriffsfehler aus. Ich wüsste gerne, warum.

....Quellcode entfernt....
Kurze Erklärung:
Du versuchst einen Zeiger zu dereferenzieren der NULL ist. Beziehungsweise du möchtest einem NULL Zeiger etwas zuweisen.

Fehlerbehebung:

Code: Select all

--- main.c.error	Thu Oct 14 22&#58;05&#58;00 2004
+++ main.c.fixed	Thu Oct 14 22&#58;04&#58;39 2004
@@ -51,7 +51,7 @@
          buf&#91;index&#93;='\0';
 
          /* Speicher freigeben und puffer in *wordarray kopieren */
-         if&#40;NULL==&#40; wordarray=malloc&#40;&#40;index+1&#41;*sizeof&#40;char&#41;&#41; &#41;&#41;
+         if&#40;NULL==&#40; *wordarray=&#40;char*&#41;malloc&#40;&#40;index+1&#41;*sizeof&#40;char&#41;&#41; &#41;&#41;
          &#123;
             fprintf&#40;stderr, "Speicher konnte nicht freigegeben werden.\n"&#41;;
             exit&#40;8&#41;;
Lange Erklärung:
ok, mal selbst das Programm ausführen...

Code: Select all

./Lateralus Wortliste.txt
In buf liegt&#58; "Wort1".
Index=5.
**wordarray hat die Groesse 1.
 *wordarray hat die Groesse 4.
  wordarray hat die Groesse 4.

Executable "Lateralus" has exited due to signal 10 &#40;SIGBUS&#41;.
autsch... ein SIGBUS ... also gucken wir mal und bauen ein paar Debugging Ausgaben ein und probieren es nochmal:

Code: Select all

./Lateralus Wortliste.txt
In buf liegt&#58; "Wort1".
Index=5.
DEBUG&#58;----------------------
  wordarray IS NOT NULL
 *wordarray IS     NULL
**wordarray

Executable "Lateralus" has exited due to signal 10 &#40;SIGBUS&#41;.
ok, *wordarray ist NULL und du versuchst auf *wordarray zuzugreifen und den Pointer zu dereferenzieren um auf **wordarry zugreifen zu können. Das _muss_ ja fehl schlagen.

Aber schauen wir uns mal deinen Quellcode an und ändern mal die malloc() Zeile für wordarray. Hier der diff:

Code: Select all

--- main.c.error	Thu Oct 14 22&#58;05&#58;00 2004
+++ main.c.fixed	Thu Oct 14 22&#58;04&#58;39 2004
@@ -51,7 +51,7 @@
          buf&#91;index&#93;='\0';
 
          /* Speicher freigeben und puffer in *wordarray kopieren */
-         if&#40;NULL==&#40; wordarray=malloc&#40;&#40;index+1&#41;*sizeof&#40;char&#41;&#41; &#41;&#41;
+         if&#40;NULL==&#40; *wordarray=&#40;char*&#41;malloc&#40;&#40;index+1&#41;*sizeof&#40;char&#41;&#41; &#41;&#41;
          &#123;
             fprintf&#40;stderr, "Speicher konnte nicht freigegeben werden.\n"&#41;;
             exit&#40;8&#41;;
und jetzt probieren wir es noch einmal:

Code: Select all

./Lateralus Wortliste.txt
In buf liegt&#58; "Wort1".
Index=5.
**wordarray hat die Groesse 1.
 *wordarray hat die Groesse 4.
  wordarray hat die Groesse 4.
In buf liegt&#58; "Wort2".
Index=5.
**wordarray hat die Groesse 1.
 *wordarray hat die Groesse 4.
  wordarray hat die Groesse 4.
In buf liegt&#58; "Wort3".
Index=5.
**wordarray hat die Groesse 1.
 *wordarray hat die Groesse 4.
  wordarray hat die Groesse 4.
Es wurden 3 Woerter eingelesen.

Executable "Lateralus" has exited with status 0.
Na also, geht doch.
It just works.

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#3 Post by Lateralus »

@heinrich
Danke! ;-)

Post Reply