Fehler bei Speicher-Allokierung



  • Hallo

    Ich habe einen merkwürdigen Fehler bei der Speicher-Allokierung, den ich mir nicht erklären kann.
    Das Programm erzeugt in tokenized.tokens ein Array mit Tokens. Ich verwende strtok nicht, da ich auch gerne mit const char als Eingabe arbeiten können will. Stattdessen verwende ich auch gute alte Pointer-Arithmetik. Die scheint aber nicht das Problem zu sein, sondern die Speicher-Allokierung. Denn am Anfang des Arrays mit Tokens werden manchmal ein oder mehrere Token "vergessen". Bin mit meinem Latein am Ende. Weiß jemand Rat?
    (Ach ja, am Ende des Programms wird der Speicher natürlich wieder freigegeben, ist hier nur rausgekürzt)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define chunk_size	2
    
    typedef struct struct_tokenized {
    	size_t	length;
    	char	**tokens;
    } tokenized;
    
    int addToken(tokenized *tok, size_t remaining, const char* start, const char* end) {
    	int i;
    
    	if(!remaining) {
    		printf("realloc (%lu):\n", (unsigned long)(tok->length+chunk_size)*sizeof(char));
    		void* tmp = realloc(tok->tokens, (tok->length+chunk_size)*sizeof(char));
    		remaining = chunk_size;
    		if(tmp == NULL)
    			return -1;
    		tok->tokens = tmp;
    	}
    	tok->tokens[tok->length] = malloc(((end-start)+1)*sizeof(char));
    	if(tok->tokens[tok->length] == NULL)
    		return -2;
    	memcpy(tok->tokens[tok->length], start, end-start);
    	tok->tokens[tok->length][end-start] = '\0';
    	tok->length++;
    
    	for(i=0; i<tok->length; i++)
    		printf("(%s) ", tok->tokens[i]);
    	printf("\n");
    
    	return remaining-1;
    }
    
    tokenized tokenize(const char* text, const char* delimiters) {
    	tokenized	tok;
    	const char*	start;
    	int remaining = 0; // Wieviel Token haben noch Platz bevor wieder allokiert werden muss?
    	tok.length = 0;
    	tok.tokens = NULL;
    	for(start = text; *text; text++) {
    		if(strchr(delimiters, (int)*text)) {
    			if(text-start) { // Token vorhanden?
    				remaining = addToken(&tok, remaining, start, text);
    				if(remaining < 0)
    					fprintf(stderr, "Fehler bei Speicher-Allokierung\n");
    			}
    			start = text+1;
    		}
    	}
    	if(text-start) {
    		if(addToken(&tok, remaining, start, text) < 0)
    			fprintf(stderr, "Fehler bei Speicher-Allokierung\n");
    	}
    	return tok;
    }
    
    int main() {
    	char* string = "eins zwei drei vier fünf";
    	char* delimiters = " ,;.:";
    	tokenized	text;
    	text = tokenize(string, delimiters);
    	return 0;
    }
    

    Ausgabe mit gcc unter Linux:

    realloc (2):
    (eins) 
    (eins) (zwei) 
    realloc (4):
    (eins) (zwei) (drei) 
    (eins) (zwei) (drei) (vier) 
    realloc (6):
    *** glibc detected *** realloc(): invalid next size: 0x0804a008 ***
    zsh: 19525 abort      ./a.out
    

    Ausgabe mit gcc unter Mac OS X:

    realloc (2):
    (eins) 
    (eins) (zwei) 
    realloc (4):
    (eins) (zwei) (drei) 
    (eins) (zwei) (drei) (vier) 
    realloc (6):
    [b](?0)[/b] (zwei) (drei) (vier) (fünf)
    

    Vielen Dank!



  • Hi,
    kann es sein, dass in addToken beim realloc sizeof(char*) stehen müsste?
    Habs nur mal kurz mitm Debugger überflogen, aber an der Stelle willst du ja
    vermutlich Platz für neue char* in deiner Struct schaffen.

    mfg exnase



  • Ach, bin ich doof! Manchmal sieht man echt den Wald vor lauter Bäumen nicht. DANKE!!!


Anmelden zum Antworten