malloc problem



  • ich brech zusammen, daran hab ich überhaupt nicht mehr gedacht

    DANKE!!!



  • hab leider noch ein problem, ich kann jetzt beispielsweise 3tage eingeben,
    allerdings liest er nur für tag 1 3temperaturen ein, ab dem 1.wert von tag 2 stürzt es wieder ab, but y????

    for(i=0; i<tage; i++)
    {
    	for(j=0; j<WERTE; j++)
    	{
    		printf("Tag %d f\201r Temperatur %d: ", i+1, j+1);
    		scanf("%d", &temp[i][j]);
    	}
    }
    

    mach ich beim einlesen was falsch??



  • Ok, wenn malloc sein muss, warum aber mit Doppelpointer? Geht doch auch so:

    double *pwerte = NULL;
    	double *sichern = NULL; // für späteres realloc
    	int werte = 0;
    	int werte_pro_tag = 3;
    	int tage = 1; // Wert wurde bereits abgefragt.
    	int i, j, k=0;
    
    	if ( NULL == (pwerte = malloc ( tage * werte_pro_tag * sizeof (double))))
    		return 1;
    	// werte einlesen
    	for ( i=0; i<tage; i++ )
    	{
    		for ( j=0; j<werte_pro_tag; j++, k++ )
    		{
    			printf ( "Tag %d Temperatur %d: ", i+1, j+1 );
    			while ( 1 != scanf ( "%lf", &pwerte[k] ))
    			{
    				puts ("Fehler in der Eingabe, bitte wiederholen!");
    				while ( getchar () != '\n' );//puffer leeren
    			}
    			while ( getchar () != '\n' );//dito
    		}
    	}
    


  • @[-|_o_I_o_|-] danke erstmal für die hilfe,
    allerdings bekomme ich immer ein runtime-error
    sobald ich einen wert eingebe stürzt es wieder ab ???

    ich geb mal kurz den code, den ich bis jetzt hab:

    double *pwerte    = NULL;
       double *sichern   = NULL; // für späteres realloc
       int werte         = 0;
       int werte_pro_tag = 3;
       int tage          = 1; // Wert wurde bereits abgefragt.
       int i             = 0;
    	int j             = 0;
    	int k             = 0;
    
    printf("F\201r wieviele Tage sollen die Messdaten eingelesen werden?");
    	printf("\nIhre eingabe: ");
    	scanf("%d", &tage);
    	printf("\n");
    
    	if( NULL == (pwerte = malloc ( tage * werte_pro_tag * sizeof (double))))
    	{
    		printf("\nEs konnte kein Speicher reserviert werden!");
    		exit(1);	
            }	
    
    	for(i=0; i<tage; i++)
        {
            for(j=0; j<werte_pro_tag; j++, k++ )
            {
                printf("Tag %d Temperatur %d: ", i+1, j+1 );
                while( 1 != scanf ( "%lf", &pwerte[k] ))
                {
                    puts ("Fehler in der Eingabe, bitte wiederholen!");
                    while ( getchar () != '\n' );//puffer leeren
                }
                while ( getchar () != '\n' );
            }
        } 
    
    	free(pwerte);
    
    	printf("\n\n");
    	return 0;
    


  • nach der zeile

    scanf("%d", &tage);

    solltest du preventiv den puffer leer machen, koennte schrott drin sein.
    die variable tage muss auf 0 geprüft werden, wenn tage 0 ist, gibt es auch 0 byte von malloc zurück.



  • du meinst fflush(stdin);?? ok das mit tage=0 hab ich verstanden, aber gehen wir mal andern fall aus. also das tage 2 oder 3 sind, warum stürzt er dann ab?? sobald ich ein wert eingebe, ist schluss (runtime-error) ??



  • nö, kein fflush. ich meine diese zeile, die den puffer leer macht:
    while ( getchar () != '\n' );//puffer leeren
    auslagern in eine funktion und nach jedem scanf aufrufen.
    zu deinem runtime error kann ich nix sagen ohne den code zu sehen, hast du da noch etwas ergänzt oder so?



  • ne ergänzt hab ich den nicht, hab den so gelassen
    ich kann ihn ja nochmal posten:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define WERTE 3
    
    int main(void)
    {
    	double *pwerte    = NULL;
       double *sichern   = NULL; // für späteres realloc
       int werte         = 0;
       int werte_pro_tag = 3;
       int tage          = 1; // Wert wurde bereits abgefragt.
       int i             = 0;
    	int j             = 0;
    	int k             = 0; 
    
    	printf("F\201r wieviele Tage sollen die Messdaten eingelesen werden?");
    	printf("\nIhre eingabe: ");
    	scanf("%d", &tage);
    	printf("\n");
    
    	if( NULL == (pwerte = malloc ( tage * werte_pro_tag * sizeof (double))))
    	{
    		printf("\nEs konnte kein Speicher reserviert werden!");		
    		exit(1);	
    	}	
    
    	for(i=0; i<tage; i++)
        {
            for(j=0; j<werte_pro_tag; j++, k++ )
            {
                printf("Tag %d Temperatur %d: ", i+1, j+1 );
                while( 1 != scanf ( "%lf", &pwerte[k] ))
                {
                    puts ("Fehler in der Eingabe, bitte wiederholen!");
                    while ( getchar () != '\n' );//puffer leeren
                }
                while ( getchar () != '\n' );
            }
        } 
    
    	free(pwerte);
    
    	printf("\n\n");
    	return 0;
    }
    

    das mit auslagern von [ while ( getchar () != '\n' ); ] hab ich noch nich da drin, aber hab einen runtime-error



  • Hi!
    Schreib das mal an den Anfang deines Programms:

    double ich_bin_ein_belohnungsbeduerftiger_compiler_und_lade_floating_point_support_nur_dann_wenn_man_mich_lieb_bittet = 1.0; // :D
    

    Klar, kannst du die Variable auch etwas abkürzen. Dann sollte das Proggie funzen.
    Gruß,
    B.B.



  • supertux schrieb:

    int *tmp;
    ...
    temp = (int **)malloc(tage*sizeof(int *));
    
    1. tmp ist ein einfacher Zeiger, aber du reserviert Speicher für einen zweifachen Zeiger.

    nö, sondern für mehrere zeiger. der cast zählt nicht, sondern das argument von 'malloc'
    🙂



  • @BigBrother lol ziemlich creative variablen namen lol
    aber danke, es läuft jetzt...
    if( NULL == (pwerte = (double*)malloc ( tage * werte_pro_tag * sizeof (double))))
    hab vor dem malloc noch das double ergänzt...

    das mit durchschnit hat wunderbar geklappt...hat sich also erledigt

    gruß
    manda



  • +fricky schrieb:

    supertux schrieb:

    int *tmp;
    ...
    temp = (int **)malloc(tage*sizeof(int *));
    
    1. tmp ist ein einfacher Zeiger, aber du reserviert Speicher für einen zweifachen Zeiger.

    nö, sondern für mehrere zeiger. der cast zählt nicht, sondern das argument von 'malloc'
    🙂

    hm, ja, das hab ich gemeint, aber falsch ausgedruckt.



  • kleine ergänzung zum programm...hab den Luftdruck noch mit drin
    ich möchte den benutzer fragen ob er noch einen weiteren tag eingeben möchte.
    also soll mit realloc neuer speicher geholt werden und dann anschließend neue durchschnittswerte (für Temperaturen und Luftdruck) berechnet werden
    allerdings soll er dann die tage dort weiter zählen, wo er am anfang aufgehört hat.
    bsp.:
    erst will ich nur 2tage eingeben(mit temperaturen und luftdruck) dann benutzer fragen ob noch ein tag eingegeben werden soll? wenn ja(bsp 1tag noch) dann soll er ab tag2 weiter zählen, also wären es 3tage und dann neu berechnen

    ich geb mal mein code bis jetzt:

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <malloc.h>
    
    int main(void)
    {
    	double *temp      = NULL;
    	double *luft		= NULL;   
       int werte         = 0;
       int werte_pro_tag = 3;
       int tage          = 1; 
       int i             = 0;
    	int j             = 0;
    	int k             = 0; 
    	double summeT     = 0.0;   
    	double summeL		= 0.0;
    
    	printf("F\201r wieviele Tage sollen die Messdaten eingelesen werden?");
    	printf("\nIhre eingabe: ");
    	scanf("%d", &tage);
    	printf("\n");	
    
    	//Speicher für Temperaturen reservieren
    	if( NULL == (temp = (double*)malloc(tage * werte_pro_tag * sizeof(double))) )
    	{
    		printf("\nEs konnte kein Speicher reserviert werden!");		
    		exit(1);	
    	}	
    	//Speicher für Luftdruck reservieren
    	if( NULL == (luft = (double*)malloc(tage * sizeof(double))) )
    	{
    		printf("\nEs konnte kein Speicher reserviert werden!");		
    		exit(1);	
    	}
    
    	for(i=0; i<tage; i++)
       {
    		printf("\nTag: %d\n", i+1);
    
    		for(j=0; j<werte_pro_tag; j++, k++ )
          {
    			printf("  Temperatur %d: ", j+1 );
             while( 1 != scanf ( "%lf", &temp[k] ))
             {
    				puts("Fehler in der Eingabe, bitte wiederholen!");
                while(getchar () != '\n');//puffer leeren
             }			
             while(getchar () != '\n');
          }		
    		printf("     Luftdruck: ");
    		scanf("%lf", &luft[i]);
       } 	
    
    printf("\n\n");
    	/*
    	printf("Wollen Sie weitere Tage eingeben[j/n]?");
    	if('j' == getch())
    	{
    		scanf("%lf", &tage);
    
    		if( NULL == (temp = (double*)realloc(temp, _msize(temp) + tage * sizeof(double)) ))
    		{
    			printf("\nEs konnte kein Speicher reserviert werden!");		
    			exit(1);	
    		}		
    	}
    	else
    	{
    		printf("\n***Der reservierte Speicherplatz wurde wieder freigegeben***");
    		printf("\n***Das Programm wird beendet***");
    	}*/
    
    	for(i=0; i<=k; i++)//durchschnitt Temperaturen
    	{
    		summeT += temp[i];	
       }
    
    	for(i=0; i<tage; i++)//durchschnitt Luftdruck
    	{
    		summeL += luft[i];
    	}
    
    	summeT /= k;
    	summeL /= (k/3);
    
    	printf("\nDurchnittstemperatur \201ber %d Tag(e): %f", k/3, summeT);
    	printf("\nDurchnittsluftdruck  \201ber %d Tag(e): %f", k/3, summeL);
    
    	free(temp);
    	free(luft);
    
    	printf("\n\n");
    	return 0;
    }
    

    den teil mit realloc hab ich auskommentiert...weil ich mir nicht sicher bin ob ich es an der richtigen stelle machen und wie ich dann wieder die werte einlese??
    hoffe ihr könnt mir noch helfen!!
    danke schonmal

    gruß
    Manda



  • MandaJohn schrieb:

    hab vor dem malloc noch das double ergänzt...

    Das kannst du beruhigt wieder in die Tonne hauen. Warum? Guckst du hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-206606.html

    MandaJohn schrieb:

    kleine ergänzung zum programm...hab den Luftdruck noch mit drin

    scanf("%d", &tage);
    

    //...

    Den Rückgabewert von scanf solltest du prüfen und nach jedem scanf solltest du den Puffer leeren. Wenn z.B. ein Buchstabe eingegeben wird, funktioniert das Programm nicht richtig.
    Davon kannst du dich überzeugen, indem du dieses Beispiel übersetzt und beim ersten scanf einen Buchstaben eingibst:

    int main ()
    {
    	double val;
    	scanf ( "%lf", &val );
    	printf ( "%lf\n", val );
    	scanf ( "%lf", &val );
    	printf ( "%lf\n", val );
    	return 0;
    }
    

    Scanf ist also mit Vorsicht zu benutzen.

    Die Funktion realloc funktioniert im Prinzip wie malloc. Der zusätzliche Parameter zeigt auf den Speicherbereich, der verkleinert/vergrößert werden soll.
    Das hier:

    _msize(temp)

    funktioniert nicht. Dem Zeiger temp kann man keine Infos über die Anzahl der Elemente entnehmen, auf die er zeigt.
    Die Anzahl musst du separat speichern.



  • oh du meinst ich müsste dann einen neuen zeiger definieren und dort die weiteren tage speichern??
    also: double *sichern = NULL;
    aber müsste ich nicht hier auch mit malloc arbeiten?? oder könnte ich auch realloc verwenden?
    weil ich eigentlich dachte, das ich mit realloc einfach neuen speicher dazu holen kann(was ich eigentlich auch soll, also realloc verwenden), und dann auf *temp die nächsten tage speichern kann...
    oder seh ich das falsch??



  • MandaJohn schrieb:

    oder seh ich das falsch??

    nee, das stimmt schon. mit 'realloc' kannste was dranhängen, allerdings kann's auch schiefgehen. deshalb nicht so:

    void *p = malloc(...);  
    ...
    p = realloc (p, ...);   // wenn realloc fehlschlägt ist dein pointer futsch
    

    sondern so:

    void *p = malloc(...); 
    void *q;                // zwischenspeicher für realloc
    ...
    q = realloc (p, ...);   // versuch noch was dranzuhängen
    if (q)
       p = q;               // hat geklappt
    

    🙂



  • @+fricky
    du meinst es so:

    if('j' == getch())
    {
          scanf("%lf", &tage);
    //sichern ist neuer pointer, und temp war der alte wo die ersten Tage drin sind
          if( NULL == (sichern = (double*)realloc(temp, _msize(temp) + werte_pro_tag * tage * sizeof(double)) ))
          {
    	printf("\nEs konnte kein Speicher reserviert werden!");		
    	exit(1);	
          }
    	temp = sichern;
    }
    else
    {
    printf("\n***Der reservierte Speicherplatz wurde wieder freigegeben***");
    printf("\n***Das Programm wird beendet***");
    }
    

    ich hoffe ich versteh es jetzt richitg???

    /Edit: was könnte denn der Grund sein das "realloc" nicht klappt? das man nicht genügend RAM hat?? oder auch was anderes??



  • MandaJohn schrieb:

    /Edit: was könnte denn der Grund sein das "realloc" nicht klappt? das man nicht genügend RAM hat?? oder auch was anderes??

    alles mögliche. über den grund schweigt sich realloc leider aus. sogar 'malloc' selbst kann scheitern.
    🙂



  • Big Brother schrieb:

    Das hier:

    _msize(temp)

    funktioniert nicht.

    Ohoh, Bruder. Guckst du MSDN, dann siehst du es geht doch.
    Die Funktion kannte ich bisher gar nicht.
    :p



  • @B.B
    Entschludige, aber ich bin gerade nicht bisschen schlauer geworden.
    _msize(temp) geht nicht? damit wollte ich eigentlich nur die größe ermitteln, die schon reserviert ist.
    Um dann was dazu hängen.
    Aber ich google mal...


Anmelden zum Antworten