Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Dynamische Felder

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
20.04.2008, 13:20 Uhr
KFC Embryo
Ein Huhn


Hallo,

ich nerv mal wieder :-)

Ich möchte jetzt eine Funktion schreiben, die Zahlen aus einer Datei ausliest.
das Funktioniert soweit noch.

Aber die Zahlen die aus der Datei ausgelesen werden sollen in einem dynamischen Feld gespeichert werden.

Ich möchte sie später sortieren und dann wieder in die Datei zurückschreiben.

Jetzt weiß ich aber net wie ich in einer Funktion ein dynamisches Feld anlegen kann.

Meine Idee:


Code:

.
.
.
int * arr[];

arr = (int*) malloc(sizeof(int));




Wenn ich das so mache habe ich doch mit ar einen Zeiger der mir auf dem Heap dynamischen Speicher anlegt oder?

Wenn ja wie kann ich dann aus einer anderen Funktion heraus darauf wieder zugreifen?
Oder ist dieser Zeiger automatisch Global, was ich irgendwie nicht glaube.

Ich Danke.

gruß
--
An nescis, mi fili, quantilla prudentia mundus regatur?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.04.2008, 15:17 Uhr
xXx
Devil


Hmm naja du reservierst Speicher aufm Heap, wobei du jetzt für 1 Element Speicher anforderst ... ob du das wirklich willst


C++:
void foo(int* arr, size_t size);

int main()
{
    const unsigned int element_count = 10;
    int* data;
    data = (int*)malloc(sizeof(int) * element_count);
    foo(data, element_count);
    free(data);
}

void foo(int* arr, size_t size)
{
    int i;
    for (i = 0; i < size; i++) printf("%02d. Element: %d", i, arr[i]);
}
so in etwa denke ich mal ging das unter C
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.04.2008, 19:15 Uhr
KFC Embryo
Ein Huhn


Mh... ok das half mir jetzt nicht so richtig weiter, sorry, kann sein das ich mich etwas dumm anstelle.

Ich hab jetzt folgenden Queltext:


Code:


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

int* ReadNumbers(FILE *fin, int *n);
void WriteNumbers(FILE *fout, int *arr, int n);
void sort (int arr[], int n);

int* ReadNumbers(FILE *fin, int *n)
{
    int c = 0, alternativen = 0;
    
    n = (int*) malloc(sizeof(int)* 25); // Die Anzahl der Zahlen die Sortiert werden sollen ist 25

    while(c = fgetc(fin) != EOF){        //Ich zähle trotzdem noch einmal die Zahlen
        if((c = ' ') || (c = '\n')){    
            n++;                        //Ich denke hier ist mein erster fehler ich "counte" den Zeiger
        }else{
            alternativen++;                    //unnötig aber fängt die alternativen ab
        }
    }
    return n;                            //Ich gebe eine Zeiger zurück, wie es die Funktion verlangt
}

void WriteNumbers(FILE *fout, int *arr, int n)
{
    int i;
    
    arr = fopen(fout,"w");                //Ich bilde einen Zeiger auf eine geöffnete Datei
    
    for(i=0; i < n; i++){                
        fprintf(arr[i], "%d", fout);
    }
}


void main (void)
{  
  
   char filename[256];
   int n, *p;
   FILE *infp, *outfp;  
  
   printf("Bitte die zubearbeitende Datei angeben: ");
   scanf("%s", filename);
  
   if ((infp = fopen(filename,"r")) == NULL ) {
       printf("Datei mit dem Namen %s konnte nicht geoeffnet werden\n");
       exit(1);
   }    
  
   if ((outfp = fopen(filename,"w")) == NULL ) {      
       printf("Datei mit dem Namen %s konnte nicht geoeffnet werden\n");
       exit(1);
   }          
   p = ReadNumbers(infp, &n);  
   sort(p,n);  
   WriteNumbers(outfp, p, n);  
   fclose(infp);  
   fclose(outfp);
}
void sort (int arr[], int n)
{
   int i, j, temp;
   for (i=n; i>0; i--)      
       for (j=0; j<i-1; j++)        
           if (arr[j]>arr[j+1]) {            
               temp = arr[j];            
               arr[j] = arr[j+1];            
               arr[j+1] = temp;         }
   return;
}





Es sollen alle Zahlen eingelesen werden.
Diese Zahlen sollen dann sortiert werden.
Danach sollen sie wieder in die Datei aus der sie stammen geschrieben werden, sortiert.

Die erste der Zahlen ist die Anzahl der Zahlen die Sortiert werden sollen.

Hier die .txt:


Code:

25
3
4
2
11
7
8
56
-76
4
3
2
6
7
8
7
5
34
67
1000
559
4
-56
34
2
87




Ich bedank mich schon einmal.

Gruß
--
An nescis, mi fili, quantilla prudentia mundus regatur?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.04.2008, 00:35 Uhr
~Kest
Gast


Hi!


C++:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>


void einlesen(const char *dName, int **arr, size_t *anz){
    FILE *datei;
    if((datei = fopen(dName, "r")) == NULL)
        return;


    char buf[256];
    while(fgets(buf, 256, datei) != NULL){
                     char *_zg;
                     int zahl = (int)strtol(buf, &_zg, 10);
                     if(buf == _zg)
                            continue;
                            
                     *arr = (int *)realloc(*arr, (*anz + 1)*sizeof(int));
                     (*arr)[(*anz)++] = zahl;
    }

    fclose(datei);
    }


int my_sort(const void *a, const void *b){
    return *(int *)a - *(int *)b;
    }
    

void schreiben(const char *dName, int *arr, size_t anz){
     FILE *datei;
     if((datei = fopen(dName, "w")) == NULL)
        return;
        
     int i;
     for(i=0; i<anz; i++)
              fprintf(datei, "%d\n", arr[i]);
              
     fclose(datei);
     }


int main(void)
{
    int *arr = NULL;
    size_t anz = 0;

    einlesen("bla.txt", &arr, &anz);
    
    if(anz > 2)
           qsort(arr, anz, sizeof(int), my_sort);
          
    schreiben("alolo.txt", arr, anz);

    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.04.2008, 10:12 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Wenn


C++:
*arr = (int *)realloc(*arr, (*anz + 1)*sizeof(int));



schief geht ist dein vorheriges Array im Sack und du kriegst Speicherlöcher ;-)

Warum nicht gleich das Array mit der richtigen Größe initialisieren wenn die erste Zahl in der Datei die Anzahl angibt?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
25.04.2008, 10:51 Uhr
KFC Embryo
Ein Huhn


mh.. ich hab das jetzt erst einmal stückweise bearbeitet:


Code:


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

int* ReadNumbers(FILE *fin, int *n);

int main (void)
{
    char filename[256];
    FILE *infp;
    int i,n;
    int *p;
    
    printf("Bitte den Dateipfad angeben: ");
    scanf("%s", filename);

    infp = fopen(filename, "r");
    p = ReadNumbers(infp, &n);

    for(i=0;i<n;i++){
        printf("%d",p[i]);
        printf("\n");
    }
    return 0;
}

int* ReadNumbers(FILE *fin, int *n)
{
    int x,i;
    int *arr;

    x = fscanf(fin, "%d", &n);

    if(x == 0){
        printf("Beim lesen der Datei ist ein Fehler aufgetreten: \n");
    }else{
        arr = (int*) malloc((sizeof(int))*n;   <----- Probleme beim allokieren
    }
    for(i=0; i<x; i++){
        fscanf(fin, "%d", &n);   <----------- Manipulieren von Adresse?
        arr[i] = (n+1)+i;
    }
    return arr;
}



Dieser Code soll bezwecken das die Zahlen der angegebenen Datei in das Dynamisch erzeugte Feld gespeichert werden.

Die Funktion ReadNumbers liefert dann einen Zeiger auf das Feld zurück.
Dann soll in main dieses Feld ausgegeben werden.

Mein Problem besteht erstens darin das ich Probleme hab beim Speicher allokieren und zweitens, dass ich mir irgendwie nicht vorstellen kann wie ich die Adresse von n so manipuliere damit sie nach jedem Schleifendurchlauf auf die Zahl zeigt die eingelesen werden soll.

Hoffe einer von euch weiß weiter.
--
An nescis, mi fili, quantilla prudentia mundus regatur?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
25.04.2008, 11:04 Uhr
ao

(Operator)


Also, erstmal GAAANZ wichtig:

Hört endlich auf, die Rückgabe von malloc / calloc / realloc umzucasten, das taugt nur dazu, Fehler zu verschleiern!

malloc retourniert einen void*, das ist kompatibel zu allen anderen Zeigertypen. Der einzig richtige Code ist

C++:
#include <stdlib.h> /* malloc-Prototyp holen */
int * irgendwas = malloc (1024);



Wer hier Fehler bekommt, kompiliert nicht in C, sondern in C++ und sollte daher nicht malloc benutzen, sondern new.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
25.04.2008, 11:55 Uhr
KFC Embryo
Ein Huhn


Hi,

@ao: Wenn ich es so mache wie du sagst:


Code:

int *arr = malloc(n*sizeof(int));



bekomme ich folgenden Fehler:


Code:

error C2296: '*': Ungültig, da der linke Operand vom Typ 'int *' ist





Zitat von ao:

Hört endlich auf, die Rückgabe von malloc / calloc / realloc umzucasten, das taugt nur dazu, Fehler zu verschleiern!



Vermutlich hast du recht aber egal wo ich bisher lass immer wird das "void" gecastet.
z.B.:

www.galileocomputing.de/openbook/c_von_a_bis_z/c_016_001.htm
http://home.fhtw-berlin.de/~junghans/cref/FUNCTIONS/malloc.html

Und auf den Folien unseres Profs. auch.
Versteh ich da was grundlegendes Falsch?

Gruß
--
An nescis, mi fili, quantilla prudentia mundus regatur?

Dieser Post wurde am 25.04.2008 um 11:55 Uhr von KFC Embryo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
25.04.2008, 14:30 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Naja der fehler ist, "you shall not cast void".

Ihr kompiliert nicht nach C sonst käme der Fehler nicht. ihr kompiliert als C++-Code. und da hat malloc eig nichts zu suchen.

Achso: und das wird natürlich auch nicht richtiger, selbst wenn der Prof das auf seinen Folien hat oder irgendwelche Bücher (die meist von dem gleichen "Typ" von Prof geschrieben wurden ...) das so steht.

Die Rückgabe von *alloc soll man nicht casten, und wenn mans müsste ists fehl am Platz.
--
class God : public ChuckNorris { };

Dieser Post wurde am 25.04.2008 um 14:32 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
25.04.2008, 21:42 Uhr
Hans
Library Walker
(Operator)



Zitat von ao:
Hört endlich auf, die Rückgabe von malloc / calloc / realloc umzucasten, das taugt nur dazu, Fehler zu verschleiern!

malloc retourniert einen void*, das ist kompatibel zu allen anderen Zeigertypen. Der einzig richtige Code ist

C++:
#include <stdlib.h> /* malloc-Prototyp holen */
int * irgendwas = malloc (1024);





Du meinst also, man soll da dem Compiler das (implizite) casten überlassen, richtig?


Zitat von ao:
Wer hier Fehler bekommt, kompiliert nicht in C, sondern in C++ und sollte daher nicht malloc benutzen, sondern new.

Fehler nicht, aber 'ne Warnung: " Nonportable pointer conversion", ansonsten übersetzt er ohne weiteres.
Ich hab aus dem Beispiel mal ein Testprogramm gebaut:

C++:
#include <stdio.h>
#include <stdlib.h> /* malloc-Prototyp holen */

int main()
{
  int *irgendwas, i;

  printf ("\nsizeof(int) = %d\n", sizeof(int));
  *irgendwas = malloc (1024);
  printf (".");
  for (i=0; i<128; i++)
    {  
        printf ("%d\n", i);
      *(irgendwas+i) = i;
    }
/* der Rest ist unerheblich */


Soweit ich weis, bekomme ich hier 1024 Byte Speicher zugewiesen, d.h. da ein Integer auf meinem System 4 Byte gross ist, müsste Platz für 256 integer sein. Das Programm steigt aber bereits bei i=33 mit einem "invalid page fault" aus. Wo liegt da mein Denkfehler??

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 25.04.2008 um 21:43 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: