Erstes Programm: "Laufzeit"fehler und Projektidee



  • ⚠ sizeof() bei einem Pointer, gibt dir die Größe des Pointers, nicht die Größe des Speichers auf den er zeigt. (Geht auch nicht, das kann man nicht rausfinden)

    sizeof(Zeiger) ist i.A 4 bei 32-Bit Systemen und 8 bei 64-Bit Systemen.



  • Also muss ich quasi "händisch"/manuell über die Zeichenkette bis zu dem '\0'-Zeichen iterieren?

    Danke erst mal 🙂



  • Ist bei C-Strings eh sinnvoller, da das Array ja auch größer sein kann als der String darin.

    Warum nimmst du nicht strcmp() für den Vergleich (dafür ist es im Standard).
    Oder schaust dir mal den Code dafür an.



  • Globale Variablen sind Schrott.
    Das wird nicht dadurch besser, dass auch verkettete Listen hinzukommen.
    Potenziert werden deine Probleme auch noch durch mangelndes Verständnis von Array und Zeiger, wie du mit deiner sizeof-Verwendung dokumentierst.

    Definiere dir deinen Stringtyp und verwalte diesen in einer einfachen Liste, die sich die Anzahl der Elemente merkt:

    #define STRING_SIZE 20
    
    typedef char MeinString[STRING_SIZE+1];
    typedef struct Node {
        MeinString *liste;
        size_t x;
    } Liste;
    

    Als Ergebnis reduzierst du den Codeumfang erheblich, dafür steigerst du die Übersichtlichkeit.



  • Aha, hier schreibt wieder jmd., der voll die Ahnung hat...

    Nur zur kenntnisnahme, ich habe sizeof entfernt und du hast mit typedef struct .... .... bereits eine globale Variable definiert.

    (Einfach) Verkettete Listen sind was für Langweiler (und in jeder Laufzeitanalyse unterirdisch). Mindestens ein BinTree sollte drin sein.

    Verbessert sieht das jetzt so aus (die unsinnigen Ausgaben in der main seien mal dahingestellt):

    /*
     * Kommentar
     */
    
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define STRING_SIZE 20
    
    typedef struct Node {
    	char str[STRING_SIZE];
    	struct Node *left;
    	struct Node *right;
    } Node;
    
    Node *tree = NULL;
    
    void cop1(char *str, Node *newNod) {
    	int i;
    	for (i = 0; str[i] != '\0' && i < STRING_SIZE - 1; i++)
    		newNod->str[i] = str[i];
    	for(; i < STRING_SIZE - 1; i++) /* optionally */
    		newNod->str[i] = '*';
    	newNod->str[i] = '\0';
    	newNod->left = NULL;
    	newNod->right = NULL;
    }
    
    int trueOrFalse(void) {
    	return rand() % 2;
    }
    
    void add1(Node *nod, Node *newNod) {
    	if (nod->left == NULL)
    		if (nod->right == NULL)
    			if (trueOrFalse())
    				nod->left = newNod;
    			else
    				nod->right = newNod;
    		else
    			nod->left = newNod;
    	else if (nod->right == NULL)
    		nod->right = newNod;
    	else if (trueOrFalse())
    		add1(nod->left, newNod);
    	else
    		add1(nod->right, newNod);
    }
    
    void add(char *str) {
    	Node *newNod = (Node *) malloc(sizeof(Node));
    	cop1(str, newNod);
    	if (tree == NULL) {
    		tree = newNod;
    		return;
    	}
    	add1(tree, newNod);
    }
    
    void printTree1(Node *nod, int *val) {
    	if (nod == NULL)
    		return;
    	printf("%-3i%-19s%7p%7p%7p\n", ++(*val), nod->str, nod, nod->left, nod->right);
    	printTree1(nod->left, val );
    	printTree1(nod->right, val);
    }
    
    void printTree(void) {
    	int val = 0;
    	printTree1(tree, &val);
    }
    
    int compare(char *str1, char *str2) {
    	int i;
    	for (i = 0; str1[i] != '\0' && str2[i] != '\0'; i++)
    		if (str1[i] != str2[i])
    			return 0;
    	return 1;
    
     /* printf("%i\n", compare("", ""));          1
    	printf("%i\n", compare("eins", "eins"));  1
    	printf("%i\n", compare("eins", "einse")); 1
    	printf("%i\n", compare("einse", "eins")); 1
    	printf("%i\n", compare("e1ns", "einse")); 0
    	printf("%i\n", compare("einse", "e1ns")); 0 */
    }
    
    int len(char *str) {
    	int i;
    	for (i = 0; str[i] != '\0'; i++)
    		;
    	return ++i;
    }
    
    void appendChar(char **ptrptr, char ch) {
    	int i;
    	int laen = len(*ptrptr);
    	char *ptr = (char *) malloc(laen + 1);
    	for (i = 0; (*ptrptr)[i] != '\0'; i++)
    		ptr[i] = (*ptrptr)[i];
    	ptr[i++] = ch;
    	ptr[i] = '\0';
    	free(*ptrptr);
    	*ptrptr = ptr;
    }
    
    void replaceChar(char **ptrptr, char ch) {
    	(*ptrptr)[len(*ptrptr) - 2] = ch;
    }
    
    void removeChar(char **ptrptr) {
    	int i;
    	int laen = len(*ptrptr) - 2;
    	char *ptr = (char *) malloc(laen + 1);
    	for (i = 0; i < laen; i++)
    		ptr[i] = (*ptrptr)[i];
    	ptr[i] = '\0';
    	free(*ptrptr);
    	*ptrptr = ptr;
    }
    
    int search1(char *str, Node *nod, char **ptrptr) {
    	if (nod == NULL)
    		return 0;
    	if (compare(str, nod->str))
    		return 1;
    	appendChar(ptrptr, 'L');
    	if (search1(str, nod->left, ptrptr  ))
    		return 1;
    	replaceChar(ptrptr, 'R');
    	if (search1(str, nod->right, ptrptr ))
    		return 1;
    	removeChar(ptrptr);
    	return 0;
    }
    
    char * search(char *str) {
    	char *ptr = "";
    	char **ptrptr = &ptr;
    	printf("%i\n", search1(str, tree, ptrptr));
    	return *ptrptr;
    }
    
    int main(void) {
    	int i;
    	int array[10];          /* Deklaration */
    	int *pointer1, *pointer2;
    	pointer1 = array;       /* pointer1 auf Anfangsadresse von array */
    	pointer2 = array + 3;   /* pointer2 auf 4.Element von array      */
    
    	array[0]      = 99;     /* array[0] */
    	pointer1[1]   = 88;     /* array[1] */
    	*(pointer1+2) = 77;     /* array[2] */
    	*pointer2     = 66;     /* array[3] */
    
    	for (i = 0; i < 10; i++)
    		printf("%5i\n", array[i]);
    
    	srand((unsigned) time(NULL));
    
    	for (i = 0; i < 1; i++) {
    	add("eins");
    	add("Zwei");
    	add("drei");
    	add("Vier");
    	add("fuenf");
    	add("Sechs");
    	add("sieben");
    	add("Acht");
    	add("neun");
    	add("!!Sehr laaannngggeeer String/Zeichenkette!!");
    	}
    	printTree();
    
    	printf("%i\n", compare("", ""));
    	printf("%i\n", compare("eins", "eins"));
    	printf("%i\n", compare("eins", "einse"));
    	printf("%i\n", compare("einse", "eins"));
    	printf("%i\n", compare("e1ns", "einse"));
    	printf("%i\n", compare("einse", "e1ns"));
    
    	printf("%s\n", search("Acht"));
    
    	for (i = 0; i < 10; i++)
    		printf("%i\n", trueOrFalse());
    
    	getchar();
    	return EXIT_SUCCESS;
    }
    


  • regInfo000? schrieb:

    Nur zur kenntnisnahme, ich habe sizeof entfernt und du hast mit typedef struct .... .... bereits eine globale Variable definiert.

    Du hast keine Ahnung.
    Du hast keine Ahnung von typedef, Deklaration und Definition.
    Du hast keine Ahnung, wovon du redest.



  • Du musst dir dringend realloc ansehen!
    Das ist eine Standardfunktion.

    Den Speicher vom Stringliteral aus Zeile 139 (der Leerstring) willst du irgendwann in Zeile 104 frei geben. Das geht nicht!

    Eine void-Funktion mit einem Doppelzeiger als Paramter ist schlechtes Design.



  • Streng genommen wird free("") nicht aufgerufen, denn vor jedem removeChar wird einmal append/replaceChar aufgerufen... Aber vom Design her ist das nicht so Banane.

    Aber dann bleibt eigentlich nur ein Array mit vorher festgelegter Größe oder ein pointer auf irgendeine Datenstruktur oder eine globale Variable übrig.

    Bei einer festgelegten Größe darf der Binärbaum nicht tiefer/höher als z. B. 20 sein. (2^20 ist auch schon viel, aber ein Binärbaum kann immer auch eine Liste sein.)

    Es ginge auch ein integer typ, 0==nicht gefunden, 1==Wurzel, 5==L usw.

    Selbstverständlich ist das neu allokieren und kopieren nicht gerade schnell, aber zum lernen ist das 1a. 😞

    Bibliotheksfunktionen, Schnittstellen oder wie auch immer kommen erst dran, wenn ich die einfachen Sachen gelernt habe.

    Frage,: was ist zulässig (was passiert nach der Abarbeitung einer Funktion):

    return &321;
    
    int i = 321;
    return &321;
    
    int i = 321;
    return i;
    

    ?

    Ich muss das wissen, ob ich z. B.:

    char *ptr = "";
        char **ptrptr = &ptr;
        doSomethingWith(ptrptr);
        return ptr or *ptrptr;
    

    schreiben darf, wegen automatischen Variablen und so etwas. - Danke.



  • regInfo000? schrieb:

    Streng genommen wird free("") nicht aufgerufen, denn vor jedem removeChar wird einmal append/replaceChar aufgerufen..

    Die Zeile 104 ist in appendChar.
    Aufrufreihenfolge ist: search (Z141)-> search1 (Z128)-> appendChar (Z104)-> free -> bang!

    Dein Code gekürzt:

    char *ptr = NULL;  // handle it
        doSomethingWith(&ptr);
        return ptr;  // der Zeiger ptr hört hier auf zu existieren, aber nicht das, worauf er zeigt (wegen malloc aus doSomethingWith).
    


  • Nabend,

    ich möchte eine Zahl (int) als Binärzahl / in Binärformat der Länge 2 per/via printf() in ANSI-C auf dem Terminal ausgeben.

    Hintergrund:

    int i = ((a-1)<<1)|(b-1);
    printf("Mode: %b\n", i);
    

    %2b funktioniert nicht.

    Querverweis (nicht Stack Overflow): http://www.osxentwicklerforum.de/index.php?page=Thread&threadID=806

    Was muss ich jetzt zu tun?


  • Mod

    regInfo000? schrieb:

    Querverweis (nicht Stack Overflow): http://www.osxentwicklerforum.de/index.php?page=Thread&threadID=806

    Was muss ich jetzt zu tun?

    😕 Den verlinkten Thread lesen?


Anmelden zum Antworten