BlackBoard » Design, Programmierung & Entwicklung » Programmieren » C dynamische Speicherreservierung » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen dynamische Speicherreservierung
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Flanders
unregistriert
dynamische Speicherreservierung       Zum Anfang der Seite springen

Hallo alle Miteinander !!!

Ich habe da mal ein kleines Problem. Kurze Vorgeschichte:
Wir haben in der Schule mal ein kleines Programm geschrieben, welches die Primzahlen von 1-100 ausgibt (Sieb des Erotosthenes). Dazu hatten wir ein Array mit 99 "Stellen". Und man konnte halt nur die Primzahlen bis 100 "sehen".
Nun ist es unsere Aufgabe, das Prgramm so umzuschriebn das der Benutzer am anfang eingeben kann bis zu welcher Zahl das Sieb des Erotosthenes gehen soll und das Primzahl Array soll nur gnau so viel Speicher verwenden wie es Primzahlen gibt. Das alles sollen wir dann mit der Dynamischen Speicher resvervierung machen.
In C (NICHT C++)

So ich habe es natürlich auch shcon ausprobiert bekomme es aber irgendwie nicht richtig hin. Wäre Nett würdet ihr ir helfen. Hier ist der Code (soweit)

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

int main()
{

/* Variablen deklarieren/ intialisieren */
unsigned int i = 0;
unsigned int Anzahl = 0;
int *pZahlen = NULL;


printf("\nGeben sie eine Zahl ein bis zu der sie die Primzahlen haben möchten:\t");
scanf("%u", &Anzahl);


/* Speicher reservieren */
pZahlen = (int *)calloc(sizeof(int), Anzahl);


/* Test ob Reservierung geklapt hat */
if (pZahlen == NULL)
{
printf("\nEs konnten keine %u Bytes Speicher reserviert werden!\n", sizeof(int) * Anzahl);
return 1;
}





/* hier ist dieses Sieb des Eratostthenes lasst euch nicht von den anderen Variablen Namen verwirren , die gehören noch zu dem anderen Programm ;-)*/
for(i=2; i<M/2; i++)
{
if(ZR[i] > 0)
{
for(j=i*2; j<M; j+=i)
{
ZR[j]=0;
}
}
}

/* Weiter bin ich noch nicht */
free(pZahlen);

return 0;
}

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Flanders: 03.03.2003 19:24.

03.03.2003 19:22
Compuholic Compuholic ist männlich
knows where he wants to go tomorrow


images/avatars/avatar-552.jpg

Dabei seit: 19.10.2002
Beiträge: 819
Herkunft: München

      Zum Anfang der Seite springen

Naja mir fällt da grad was auf:

Wenn der Benutzer n als Obergrenze eingibt allokierst Du Speicher für n-Elemente. Nicht jede Zahl ist aber eine Primzahl. Du müßtest wenn eine Primzahl gefunden wird dynamisch mehr Speicher allokieren.

Ansonsten ist das doch schon mal ein Anfang. "calloc" gibt die einen Pointer auf den allokierten Speicher zurück. Denn Du dann direkt ansprechen mußt. Das n-te Element wäre dann (bei 0 angefangen).
BasePointer + sizeof(int) * Elementnummer

Um die Größe des allokierten Speichers zu ändern: Schau Dir mal die Funktion "realloc" an.
04.03.2003 01:00 Compuholic ist offline E-Mail an Compuholic senden Homepage von Compuholic Beiträge von Compuholic suchen
Flanders
unregistriert
      Zum Anfang der Seite springen

Ich will jetzt wissen wie ich diesem Array die Zahlen zuweisen kann.
Sprich wenn der Benutzer 10 eingubt sollen alle Zahlen von 0-9 in das Array geschriben werden.

Darasu solllen dann ahlt die Primzahlen herausgefiltert werden!!!

bitte helft mir doch !
04.03.2003 17:10
CDW CDW ist männlich
eine Simulation


Dabei seit: 12.10.2002
Beiträge: 1.329
Herkunft: CreateRemoteThread

      Zum Anfang der Seite springen

Compuholic: ich glaub, ich verstehe, was du meinst, => nur die gefundenen Zahlen speichern, das erfordert aber schon nen Umgang mit dynamischen Listen und so weit sind die wahrscheinlich noch nicht.
Flanders: technische Frage: warum arbeitest du nicht mit einem booleand Array? einfach reinschreiben (TRUE für Primzahl, sonst FALSE)
und um zahlen auszuschalten könnte man doch auch so was verwenden
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
for(i=2;i<int(sqrt(Menge));i++)
{
   for(j=2;j<int(sqrt(Menge));j++)
     {
       ZM[i*j]=FALSE;
     }
}

zum Zugriff: was meinst du? das geht doch wie sonst:
nach der Reservierung kannst du entweder:
*(pZahlen+i)=Zahl
oder
pZahlen[i]=Zahl
schreiben (zumindest laut meinem buch)
04.03.2003 17:31 CDW ist offline E-Mail an CDW senden Homepage von CDW Beiträge von CDW suchen
Flanders
unregistriert
      Zum Anfang der Seite springen

welches buch hast du?
04.03.2003 21:15
Deef Deef ist männlich
...


Dabei seit: 24.08.2002
Beiträge: 431

      Zum Anfang der Seite springen

Hi Flanders!

Ich kann Dir leider bei der Speicherverwaltung nicht helfen, aber ich durfte auch schonmal in Programm mit dem Sieb des Erotosthenes schreiben (allerdings in einer anderen Sprache) und bei mir gab es damals Punktabzug, wenn man kein boolisches Array benutzt hat ;o)

Aussage vom Prof: Das schreit grade zu danach .. das MUSS man sehen! *g*

PS: Ich hatte damals alle Zahlen, die keine Primzahlen waren durch 0 ersetzt im Array und hab deshalb in die Röhre geguckt *g*

__________________
Was sagen uns Signaturen?! 1.Ich kann Latein 2.Ich bin umheimlich tiefgründig 3.Ich kann googlen 4.Ich lese die Lyrics der Lieder die ich höre 5.Ich schreibe und denke mir Scheisse aus die keiner lesen will...
05.03.2003 06:08 Deef ist offline E-Mail an Deef senden Beiträge von Deef suchen
CDW CDW ist männlich
eine Simulation


Dabei seit: 12.10.2002
Beiträge: 1.329
Herkunft: CreateRemoteThread

      Zum Anfang der Seite springen

@Jutaro: ist das nicht der Algo von Flanders (durch 0 ersetzten) *g* und war die Sprache nicht zufällig Pascal? Bei meinem tutor ist jede funktionierende Lösung korrekt, nur wenn wir gerade bei Listen sind und jemand das Problem mit Arrays löst, gibts es keine volle Punktzahl...
Flanders: C-Programmierung von A.Willms

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von CDW: 05.03.2003 16:49.

05.03.2003 16:47 CDW ist offline E-Mail an CDW senden Homepage von CDW Beiträge von CDW suchen
Deef Deef ist männlich
...


Dabei seit: 24.08.2002
Beiträge: 431

      Zum Anfang der Seite springen

Sprache war Java und es musste direkt ein boolesches Array verwendet werden!
Ich hatte wie gesagt nen integer Array benutzt (und halt die Variationen 1 und 0) und es gab Abzug weil true und false verwendet werden mussten ...

Ähm und ja ich seh grad er hat das auch so gemacht *g* Also wie gesagt: Bei mir gabs Abzug!

__________________
Was sagen uns Signaturen?! 1.Ich kann Latein 2.Ich bin umheimlich tiefgründig 3.Ich kann googlen 4.Ich lese die Lyrics der Lieder die ich höre 5.Ich schreibe und denke mir Scheisse aus die keiner lesen will...
05.03.2003 18:27 Deef ist offline E-Mail an Deef senden Beiträge von Deef suchen
Flanders
unregistriert
Kleine Frage       Zum Anfang der Seite springen

Habe mal eine kleine Frage, dazu dieser Code:

printf("\nGeben eine ein:\t");
scanf("%u", &Prim);


/* Speicher reservieren */
pZahlen = (int *)calloc(sizeof(int), Prim);


Wird nun genau so viel Speicher reserviert wie der Benutzer eingeben hat, also wen er 10 engeben hat ist Prim ja 10, werden dann auch 10 Speicherstellen reserviert ???

/* EDIT */
Habe ein Program geschieben welche sPrimzahlen ausrechnet, mit dynamischer Speicherreservierung, doch am Ende gibt er immer eine Fehler meldung aus (Quelltext ist OK) Der Fehler jmuss in der ROR markierten Zeile stehen, doch warum kommt er ???

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

int main()
{

/* Variablen deklarieren/ intialisieren */
unsigned int i = 0;
unsigned int j = 0;
unsigned int M = 100;
unsigned int Prim = 0;
unsigned int Pr =0;
unsigned int Zahlen[99] = {0};
unsigned int test[99] = {0};
int *pZahlen = NULL;


printf("\nGeben Sie die Zahl ein, bis zu der Sie die Primzahlen haben moechten:\t");
scanf("%u", &Prim);


/* Speicher reservieren */
pZahlen = (int *)calloc(sizeof(int), Prim);


/* Test ob Reservierung geklapt hat */
if (pZahlen == NULL)
{
printf("\nEs konnten keine %u Bytes Speicher reserviert werden!\n", sizeof(int) * Prim);
return 1;
}


/* Zahlen zuweisen */
for (i=0; i<M; i++)
{
Zahlen[i] = i;
}



/* Primzahlen werden herraus gefiltert */
for(i=2; i<M/2; i++)
{
if(Zahlen[i] > 0)
{
for(j=i*2; j < M; j+=i)
{
Zahlen[j]=0;
}
}
}

j=0;
/* Primzahlen werden kopiert */
for(i=2; i<M; i++)
{
if(Zahlen[i] > 0)
{
pZahlen[j] = Zahlen[i];
j++;
}
}


printf("\n----%i----", Prim);


/* Primzahlen Ausgabe */
for(i=0; i<Prim; i++)
{
printf("\n%i", pZahlen[i]);
}


/* Speicher wird wieder freigegeben */
free(pZahlen);

return 0;
}

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Flanders: 05.03.2003 20:26.

05.03.2003 20:13
Compuholic Compuholic ist männlich
knows where he wants to go tomorrow


images/avatars/avatar-552.jpg

Dabei seit: 19.10.2002
Beiträge: 819
Herkunft: München

      Zum Anfang der Seite springen

Zur 1. Frage: Es werden keine 10 Bytes an Speicher reserviert. Eine Integer ist normalerweise 32 Bit breit. Du reserviert 10 Elemente vom Typ int. Also werden 10 * 4 Bytes (= 40 Bytes) an Speicher reserviert.

Effektiv wird wahrscheinlich noch mehr Speicher benötigt. Ich weiß z.B. von der Funktion malloc, daß die am Ende noch ein paar Bytes mehr reserviert um da einige Informationen reinzuschreiben. Außerdem wird vom Betriebssystem der Speicher wahrscheinlich aligned verwaltet..

zu 2. Ich sehe momentan keinen Fehler. Wenn Du vielleicht die Fehlermeldung genauer beschreiben könntest, wüßte ich vielleicht nach was ich suche. Das ganze Programm mag ich mir jetzt nicht anschauen *g*
05.03.2003 20:38 Compuholic ist offline E-Mail an Compuholic senden Homepage von Compuholic Beiträge von Compuholic suchen
CDW CDW ist männlich
eine Simulation


Dabei seit: 12.10.2002
Beiträge: 1.329
Herkunft: CreateRemoteThread

      Zum Anfang der Seite springen

hm, ich hab das programm mit lcc compiliert, folgende WArnungen wurden ausgegeben:
Warning c:\shutdown\lcc\helloworld\helloworld.c: 5 old-style function definition for 'main'
Warning c:\shutdown\lcc\helloworld\helloworld.c: 5 missing prototype for `main'
Warning c:\shutdown\lcc\helloworld\helloworld.c: 5 `int main()' is a non-ANSI definition
Warning c:\shutdown\lcc\helloworld\helloworld.c: 14 test is assigned a value that is never used
Warning c:\shutdown\lcc\helloworld\helloworld.c: 12 Pr is assigned a value that is never used
Compilation + link time:0.1 sec, Return code: 0

Ja, und nach eingabe geschiet nichts mehr, die CPU ist dann 100% belastet => irgendwo hängt ne Schleife...
05.03.2003 20:41 CDW ist offline E-Mail an CDW senden Homepage von CDW Beiträge von CDW suchen
Flanders
unregistriert
      Zum Anfang der Seite springen

Ja !!!
Wenn ich das hier weg mache:

/* Primzahlen werden kopiert */
for(i=2; i<M; i++)
{
if(Zahlen[i] > 0)
{
pZahlen[j] = Zahlen[i];
j++;
}
}


Kommt keine Fehler, doch was könnte hier falsch passieren ??

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Flanders: 05.03.2003 20:49.

05.03.2003 20:48
CDW CDW ist männlich
eine Simulation


Dabei seit: 12.10.2002
Beiträge: 1.329
Herkunft: CreateRemoteThread

      Zum Anfang der Seite springen

ich blick beim Konzept nicht so durch - du hast ja schon nen Array bis 99, machst zusätzlich noch einen (freien) obwohl die Zahlen immer noch begrenzt sind bis M
zum Fehler:
i<M ist das gleiche wie
i<100
aber pZahlen ist je nach dem um einiges kleiner... könnte theoretisch daran liegen...
PS: hab das mit MS VC++6 compiliert, läuft, kommt ein Fehler, hab debuggt... fehler liegt erst nach der Ausgabe, also wahrscheinlich fehlerhafte Freigabe des Speichers, genaues kann ich leider nicht sagen, da MS solchen bloatcode produzierrt, dass man nicht mehr überblickt (schade dass es in lcc nicht geht, denn der generierter ASM code ist da 3 mal kleiner und kompakter)
Wäre also möglich, dass die von dir gennante Prozedur den Stack überschreibt, so dass nicht mehr hergerichtet werden kann. Schau dir nochmal ganz genau die größen (in dieser Prozedur) so wie das reservierungskonzept an. Bin leider kein C guru aber alles läuft auf Stackoverflow hinaus...

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von CDW: 05.03.2003 21:18.

05.03.2003 21:11 CDW ist offline E-Mail an CDW senden Homepage von CDW Beiträge von CDW suchen
Flanders
unregistriert
      Zum Anfang der Seite springen

wie kann ich eigetlich testen ob genau so viele Speicher stellen freigegebn wurden ???
05.03.2003 21:17
Flanders
unregistriert
kleine Problem mit reservierung !!!       Zum Anfang der Seite springen

Ich brauche mal wieder Hilfe.
Im nachfolgenden C-Programm (nicht C++) sollen nur genau so viele Speicherstellen reserviert werden (pZahlen) wie es Primzahlen gibt.
Doch wie bekomme ich das hin.
Wenn ich das richtig sehe werden JETZT immer so viele Stellen reserviert wie der Benutzer am Anfang eingibt oder sehe ich das falsch ???

Hier ist der Quellcode.

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

int main()
{

/* Variablen, Zeiger deklarieren/ intialisieren */
unsigned int i = 0;
unsigned int j = 0;
unsigned int M = 100;
unsigned int Prim = 0;
unsigned int Pr =0;
unsigned int Zahlen[99] = {0};
int *pZahlen = NULL;


/* Bilschirmausgabe, Benutzerabfrage */
printf("\nGeben Sie die Zahl ein, bis zu der das Sieb des Eratostthenes gehen soll:\t");
scanf("%u", &Prim);


/* Speicher reservieren */
pZahlen = (int *)calloc(sizeof(int), Prim);

/* Test ob Reservierung geklapt hat */
if (pZahlen == NULL)
{
printf("\nEs konnten keine %u Bytes Speicher reserviert werden!\n", sizeof(int) * Prim);
return 1;
}


/* Zahlen zuweisen */
for (i=0; i<M; i++)
{
Zahlen[i] = i;
}


/* Primzahlen werden herraus gefiltert */
for(i=2; i<Prim; i++)
{
if(Zahlen[i] > 0)
{
for(j=i*2; j < M; j+=i)
{
Zahlen[j]=0;
}
}
}

j=0;

/* NUR die Primzahlen werden herauskopiert */
for(i=2; i<Prim; i++)
{
if(Zahlen[i] > 0)
{
pZahlen[j] = Zahlen[i];
j++;
}
}


/* Primzahlen Ausgabe */
for(i=0; i<Prim; i++)
{
printf("\n%i", pZahlen[i]);
}


/* Speicher wird wieder freigegeben */
free(pZahlen);

return 0;
}
09.03.2003 17:20
CDW CDW ist männlich
eine Simulation


Dabei seit: 12.10.2002
Beiträge: 1.329
Herkunft: CreateRemoteThread

      Zum Anfang der Seite springen

ich werde mal versuchen Programmiersprachenunabhängig zu antworten, da es ja erstens auch ein P-Sprachenunabhängies problem ist und ich zweitens des C noch nicht so ganz mächtig bin:
du siehst es komplett richtig smile es werden so viele Stellen reserviert, wie der Benutzer eingibt.
Das Problem ist jetzt: man weiß nicht vorher, wieviele Primzahlen es gibt, denn der Benutzer könnte ja 20 aber auch 100 eingeben (über 100 dürfte dein Programm nicht verarbeiten können, da du ja ein hunderter Array benutzt.
Die einfachste Lösung wäre jetzt, jedesmal, wenn eine Primzahl gefunden wird, darüf den nötigen Speicherplatz zu reservieren.Das realiesiert man am besten mit Listen.Da du ja schon Zeiger kennst,sollte es für dich kein Problem sein.
Strukturvorschlag:

typdef typzahl int;
typZeiger *zahlstructur;

struct zahlstructur
typzahl zahl;
typzeiger zNext;


inc C wäre das ungefähr so:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
typdef typzahl int;
typdef typzeiger *zahlstructur;
struct zahlstructur
  {
     typzahl zahl;
     typzeiger zNach;
  }
dann brauchst du einen Zeiger(global), der die "Wurzel" also den Anfang der Liste festhält:

typzeiger zWurzel=NULL;
zWurzel->zNach=NULL; /*auf default setzen,am besten noch in der main*/

typzeiger erstelleListe(typzeiger zAkt,typzahl zahl)
{
typzeiger ztemp;
    while (zAkt->zNach!=NULL)
      {
         zAkt=zAkt->zNach ; /*man geht bis zum ende der Liste */
      }
     ztemp=malloc(sizeof(struct zahlstructur));  
     ztemp->zNach=NULL;
     ztemp->zahl=zahl; /*die übergebene zahl reinschreiben*/
     zAkt->zNach=ztemp;
     return zAkt
}

und so nutzt du das:


void primzahlberechnnung( );
typzeiger ztemp;
   {
  ztemp=zWurzel; /*die Wurzel darf nicht verloren gehen*/  

     /*berechnen wie auch immer */
    ztemp=erstelleListe(ztemp,ergebnis);
   }

Ausgabe dürfte so aussehen:

void ausgabe(typzeiger zWurz)
{
 while(zWurz->zNach!=NULL)
{
   printf("\n%i", zWurz->zahl);
   zWurz=zWurz->zNach;
}
}

der Code ist mit vorsicht zu genießen, hab ich aus dem Kopf und wie schon erwähnt kann ich ja eigenlich kein C großes Grinsen ... aber das läuft so in Pascal und C ist ja nur schlechte Version davon Augenzwinkern

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von CDW: 09.03.2003 19:42.

09.03.2003 19:39 CDW ist offline E-Mail an CDW senden Homepage von CDW Beiträge von CDW suchen
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
BlackBoard » Design, Programmierung & Entwicklung » Programmieren » C dynamische Speicherreservierung

Forensoftware: Burning Board 2.3.6, entwickelt von WoltLab GmbH