liste verändert sich während der übergabe



  • hallo ich hab mir ne liste erstellt:

    struct list
    {
    	struct tree* leave;
    	struct list* prev;
    	struct list* next;
    };
    

    struct list* test;
    da is was drinne und das letzte test->next->...->next ist NULL

    struct list* actpos = test;
    	while (actpos->next != NULL)
    	{
    		printf("%c %i %i\n", (char)actpos->leave->character, (int)actpos, (int)actpos->next);
    		actpos = actpos->next;
    	}
    

    geht soweit perfekt!
    er hört vor dem NULL-zeiger auf.

    wenn ich das aber an folgende funktion übergebe:

    void AddNewTreeEntry(struct tree* min1, struct tree* min2, struct list* start)
    {
    	struct list* actpos = start;
    	while (actpos->next != NULL)//Error: endlosschleife: letztes next = actpos????
    	{
    		printf("%c %i %i\n", (char)actpos->leave->character, (int)actpos, (int)actpos->next);
    		actpos = actpos->next;
    	}
    	actpos->next = (struct list *)calloc(1, sizeof(struct list));
    	actpos->next->prev = actpos;
    	actpos->next->leave = (struct tree *)calloc(1, sizeof(struct tree));
    	actpos->next->leave->child0 = min1;
    	actpos->next->leave->child1 = min2;
    	actpos->next->leave->child0->parent = actpos->next->leave;
    	actpos->next->leave->child1->parent = actpos->next->leave;
    	actpos->next->leave->frequency = min1->frequency + min2->frequency;
    	actpos->next->leave->character = 0;
    }
    

    dann wird der NULL-zeiger zum zeiger auf das letzte element???
    (hab mir das im debugger angeschaut - das ist einfach Hexerei)

    PS.: nutze xubuntu 7.10 mit gcc 4.3 und eclipse 3.3.2



  • ach ja compileroptions sind
    -O0 -g3 -pg -p -pedantic -pedantic-errors -Wall -Werror -c -fmessage-length=0 -std=c99



  • stfischr schrieb:

    struct list* actpos = test;
    	while (actpos->next != NULL)
    	{
    		printf("%c %i %i\n", (char)actpos->leave->character, (int)actpos, (int)actpos->next);
    		actpos = actpos->next;
    	}
    

    tztztz Pointer nach int zu casten ist böse. Außerdem gibt es für die Ausgabe von Pointern extra %p bei printf!

    wenn ich das aber an folgende funktion übergebe:

    void AddNewTreeEntry(struct tree* min1, struct tree* min2, struct list* start)
    {
    	struct list* actpos = start;
    	while (actpos->next != NULL)//Error: endlosschleife: letztes next = actpos????
    	{
    		printf("%c %i %i\n", (char)actpos->leave->character, (int)actpos, (int)actpos->next);
    		actpos = actpos->next;
    	}
    	actpos->next = (struct list *)calloc(1, sizeof(struct list));
    	actpos->next->prev = actpos;
    	actpos->next->leave = (struct tree *)calloc(1, sizeof(struct tree));
    	actpos->next->leave->child0 = min1;
    	actpos->next->leave->child1 = min2;
    	actpos->next->leave->child0->parent = actpos->next->leave;
    	actpos->next->leave->child1->parent = actpos->next->leave;
    	actpos->next->leave->frequency = min1->frequency + min2->frequency;
    	actpos->next->leave->character = 0;
    }
    

    dann wird der NULL-zeiger zum zeiger auf das letzte element???
    (hab mir das im debugger angeschaut - das ist einfach Hexerei)

    Das kann eigentlich nicht sein. Bist du dir sicher, dass der Fehler nicht an einer anderen Stelle liegt? Tritt der Fehler bei jedem Aufruf dieser Funktion auf? Und nur beim Aufruf dieser Funktion?

    Zeig am besten mal ein minimales aber kompilierbares Beispiel, das dein Problem illustriert.

    btw. den Rückgabewert von calloc am besten nicht casten: http://www.c-plusplus.net/forum/viewtopic.php?t=206606



  • #include <stdio.h>
    #include <stdlib.h>
    //#include <stdbool.h>
    
    struct tree
    {
    	unsigned long long frequency;
    	unsigned char character;
    	struct tree* parent;
    	struct tree* child0;
    	struct tree* child1;
    };
    
    struct list
    {
    	struct tree* leave;
    	struct list* prev;
    	struct list* next;
    };
    
    struct list* ArrayToList(unsigned long long freqarr[256])
    {
    	struct list* start = (struct list *)calloc(1, sizeof(struct list));
    	struct list* actpos = start;
    	actpos->leave=(struct tree *)calloc(1, sizeof(struct tree));
    	actpos->leave->frequency=freqarr[0];
    	actpos->leave->character=0;
    	for (int i = 1; i < 256; i++)
    	{
    		if (freqarr[i] != 0)
    		{
    			actpos->next=(struct list *)calloc(1, sizeof(struct list));
    			actpos->prev=actpos;
    			actpos=actpos->next;
    			actpos->leave=(struct tree *)calloc(1, sizeof(struct tree));
    			actpos->leave->frequency=freqarr[i];
    			actpos->leave->character=(unsigned char)i;
    			actpos->next = NULL;
    		}
    	}
    	//free(freqarr); //merken für erneute erstellung des huffbaums
    	return start;
    }
    
    unsigned long long* FrequencyDistributionArray(unsigned char* input)
    {
    	unsigned long long* freqarray=(unsigned long long *)calloc(256, sizeof(unsigned long long));
    	while (*input!=0)
    	{
    		freqarray[*input]++;
    		input++;
    		freqarray[0]++;
    	}
    	return freqarray;
    }
    
    struct list* CutLowest2Values(struct list* start)
    {
    	struct list* actpos = start;
    	struct list* listmin1=start;
    	struct list* listmin2=start;
    	while (actpos->next != NULL)
    	{
    		actpos=actpos->next;
    		if (actpos->leave->frequency> 0 && (actpos->leave->frequency < listmin1->leave->frequency || (actpos->leave->frequency <= listmin1->leave->frequency)))
    		{
    			listmin1=actpos;
    		}
    	}
    	actpos=start;
    	while (actpos->next != NULL)
    	{
    		actpos=actpos->next;
    		if (actpos->leave->frequency> 0 && (actpos->leave->frequency < listmin2->leave->frequency || (actpos->leave->frequency <= listmin2->leave->frequency))&&listmin2 != listmin1)
    		{
    			listmin2=actpos;
    		}
    	}
    	if (listmin1!=start)
    	{
    		if (listmin1->next == NULL)
    		{
    			listmin1->prev->next=NULL;
    		}
    		else
    		{
    			listmin1->next->prev=listmin1->prev;
    			listmin1->prev->next=listmin1->next;
    		}
    	}
    	else
    	{
    		listmin1=NULL;
    		puts("error in cutout von listmin1");
    	}
    	if (listmin2!=start)
    	{
    		if (listmin2->next == NULL)
    		{
    			listmin2->prev->next=NULL;
    		}
    		else
    		{
    			listmin2->next->prev=listmin2->prev;
    			listmin2->prev->next=listmin2->next;
    		}
    	}
    	else
    	{
    		listmin2=NULL;
    		puts("error in cutout von listmin2");
    	}
    	listmin1->next = listmin2;
    	return listmin1;
    }
    
    void AddNewTreeEntry(struct tree* min1, struct tree* min2, struct list* start)
    {
    	struct list* actpos = start;
    	puts("selbe forschleife nach übergabe\n");
    	while (actpos->next != NULL)// hier ists ne unendlich schleife :(
    	{
    		printf("%c %i %i\n", (char)actpos->leave->character, (int)actpos, (int)actpos->next);
    		actpos = actpos->next;
    	}
    	actpos->next = calloc(1, sizeof(struct list));
    	actpos->next->prev = actpos;
    	actpos->next->leave = (struct tree *)calloc(1, sizeof(struct tree));
    	actpos->next->leave->child0 = min1;
    	actpos->next->leave->child1 = min2;
    	actpos->next->leave->child0->parent = actpos->next->leave;
    	actpos->next->leave->child1->parent = actpos->next->leave;
    	actpos->next->leave->frequency = min1->frequency + min2->frequency;
    	actpos->next->leave->character = 0;
    }
    
    struct tree* CreateHuffmanTree(unsigned char* input)
    {
    	struct list* hufflist = ArrayToList(FrequencyDistributionArray(input));
    	struct list* listmin1 = hufflist;
    	struct list* listmin2 = hufflist;
    	struct list* actpos = hufflist;
    	while (listmin1 != NULL && listmin2 != NULL)
    	{
    		listmin1 = CutLowest2Values(hufflist);
    		listmin2 = listmin1->next;
    		puts("selbe forschleife vor übergabe\n");
    		while (actpos->next != NULL)
    		{
    			printf("%c %i %i\n", (char)actpos->leave->character, (int)actpos, (int)actpos->next);
    			actpos = actpos->next;
    		}
    		AddNewTreeEntry(listmin1->leave, listmin2->leave, hufflist);
    	}
    	struct tree* huffmantreeroot = hufflist->next->leave;
    	return huffmantreeroot;
    }
    
    int main(void)
    {
    	unsigned char* text = malloc(sizeof(unsigned char)*4096);
    	text=(unsigned char *)"\nArithmetic ";
    	struct tree* huffmantreeroot = CreateHuffmanTree(text);
    	huffmantreeroot = huffmantreeroot;
    	return EXIT_SUCCESS;
    }
    

    interresant ist nur CreateHuffmanTree und AddNewTreeEntry
    weil in der ersteren funktion läufts und in der anderen nicht

    zu calloc casten: hatte ich mir mal angewöhnt weils immer fehler gab - aber es geht auch ohne 😮 tja dann halt ohne bis er mich wieder mal vollnölt 🙂

    %p genau naja so selten wie ich dieses printf benutze ... (das ganze gecaste is nur für testzwecke und kommt nicht ins endproduckt mit rein 😉 )



  • hab jetzt mal AddNewTreeEntry mit

    void testfunk(struct list* start)
    {
    	while (start->next != NULL)
    	{
    		printf("%c %i %i\n", (char)start->leave->character, (int)start, (int)start->next);
    		start = start->next;
    	}	
    }
    

    ersetzt

    selbes problem 😕



  • in deinen schleifen die auf der liste arbeiten hast du als abbruchbedingung actpos->nxt != NULL, d.h. der letze wird nie behandelt, ist das beabsichtigt?
    wenn nicht kannst du deine bedingung auf actpos != NULL ändern, das behandelt auch den fall, wenn deine liste leer ist(sprich start == NULL), sry wenn das so gewollt wäre



  • nee das is so gewollt
    weil ich damit noch arbeiten muss
    und wenner auf null steht dann geht kein ->next und kein ->prev mehr 😉



  • ach ja und die liste kann nie null sein
    das hab ich schon so geregelt



  • Edit: null muss leer heißen



  • so nun hab ich rausgefunden das es irgendwie an

    listmin1 = CutLowest2Values(hufflist);
    

    liegt sobald ich das auskommentiere is alles in ordnung

    aber wie kann das etwas verändern das erst 2 zeilen später kommt?


Anmelden zum Antworten