probleme mit pointern in C |
|
Damit versuchst du auf das letzte "Auto" zuzugreifen.
Sehen wir uns erstmal an wie das im Speicher aussieht.
code: |
1:
2:
3:
4:
5:
|
+------+------+
|Auto 1|Auto 2|
+------+------+
^
| |
|
Wenn du um Anzahl-Autos (2) weitergehst sieht das so aus:
code: |
1:
2:
3:
4:
5:
|
+------+------+
|Auto 1|Auto 2|
+------+------+
^
| |
|
Der Pfeil stellt dabei die aktuelle Speicheradresse von "pkws" dar.
Wie du siehst musst du Anzahl - 1 weiter gehen.
code: |
1:
|
pkws+=(anzahl-1); |
|
Gruß TheImaginator
|
|
22.08.2007 21:14 |
|
|
|
die gedanken hab ich mir auchschon gemacht, aber warum komm ich bei linux wie du sagst am anfang von auto3 an(was ich ja nicht will) aber bei windows aus irgendeinem grund am anfang von auto2(wie es ja gewollt ist)
zählt windows vll einfach anderst...
bzw kurze schönheitsfrage^^ wie kann ich eine funktion, die norm. zwei paramater erwartet aufrufen, ohne ihr diese zu übergeben?
im klartext, ich hab ne funktion und die ist wie fogt definiert
void funktion(struct test *,struct test*);
diese beiden pointer werden aber erst in der funktion "funktion2" definiert. wie kann ich "funktion" trotzdem von main aus aufrufen, ohne das mein kompiler mekert, too few arguments
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Schatten: 22.08.2007 21:34.
|
|
22.08.2007 21:32 |
|
|
|
Wenn du zur Laufzeit Speicher (auf dem Heap) reservierst, dann wird nicht genau die Menge an Speicher gemappt, die du benötigst, sondern immer bestimmte Speicherblöcke.
Die Implementierung von malloc unter Linux muss wohl so ausgelegt sein, dass darauf geachtet wird, wirklich nur Zugriff auf den angeforderten Speicher zu bekommen (gut).
Segmentation fault heißt im allgemeinen, dass du eine ungemappte Speicheradresse lesen/schreiben willst.
Windows geht das wohl am Arsch vorbei (schlecht).
Da sieht man es wieder:
Linux gut.
Windows schlecht.
Zitat: |
wie kann ich eine funktion, die norm. zwei paramater erwartet aufrufen, ohne ihr diese zu übergeben? |
|
Indem du sie überlädst, sprich einfach neu definierst.
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
|
void funktion(int parameter)
{
// Blabla
}
void funktion()
{
// Blabla 2
} |
|
Danach kannst du dies aufrufen:
code: |
1:
2:
|
funktion(5);
funktion(); |
|
Beide Funktionen haben denselben Namen, jedoch eine andere Implementierung.
Oder benötigst du die Parameter in der Funktion.
Dann würde ich sie am besten einfach global definieren.
|
|
22.08.2007 22:09 |
|
|
|
es hat sich erledigt
da es sich um zeiger handelte kann ich diese in main definieren...
danke trotzde
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
22.08.2007 22:17 |
|
|
|
ich weis jetzt wie ich das mit dem speicher mach.
also du hattest recht, windows schreibt beim letzten array speicher wirklich iwo in RAM rein und nichtmehr in den mit malloc angeforderten speicher.
heist ich fordere mit malloc anzahl +1 speicher an. damit bekomm ich genug speicher für alle arrays die cih brauch und noch für nen array in den ich die abbruchbedingung reinpack.
wenn ich dann
pointer+=anzahl;
eingeb komm ich hier an:
(beisp. anzahl der arrays 2)
code: |
1:
2:
3:
4:
5:
6:
7:
8:
|
+-----------------+-----------------+-----------------+
|Array mit |Array mit |Array nur für |
|Werten 1 |Werten 2 |Abbruch |
+-----------------+-----------------+-----------------+
^
|
|
|
da zeig mein zeiger dann nämlich hin wenn ich ihn mit anzahl inkrementiere. und dann kann die for schleife schön testen, ob die abbruchbedingung erfüllt ist...
also das programm sieht jetzt mit dateiverwaltung derz. so aus:
(is noch net fertig)
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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
|
#include <stdio.h>
#define MAXLEN 30
#define NEU 1
#define EINGABE 2
#define AUSGABE 3
#define LOESCHEN 4
#define ENDE 5
struct wagen {
char name[MAXLEN]; /* Name des Autos */
float speed; /* Geschwindigkeit */
int zylinder; /* Anzhl der Zilynder */
int ps; /* Anzahl der PS */
char gas; /* Art des Benzins S=Super, N=Normal, D=Diesel */
int abbruch;
};
void eingabe(struct wagen *,struct wagen *);
void ausgabe(struct wagen *,struct wagen *);
void del();
void new();
int menu();
int main()
{
struct wagen *pkws,*control;
short choice;
for(;;)
{
choice=menu();
switch (choice) {
case NEU:
new();
break;
case EINGABE:
eingabe(pkws,control);
break;
case AUSGABE:
ausgabe(pkws,control);
break;
case LOESCHEN:
del();
break;
case ENDE:
return 0;
default:
printf("Ungueltige Eingabe");
break;
}
}
system("PAUSE");
}
void eingabe(struct wagen *pkws,struct wagen *control)
{
short index,anzahl=1;
FILE *file;
char name[20],ch='N';
fflush(stdin);
printf("\n\nWie heist die Datei in die sie schreiben wollen\n");
printf("(Falls die Datei nicht existiert wird sie angelegt) ");
gets(name);
printf("\n\nWie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n');
pkws=malloc((anzahl+1)*sizeof(struct wagen));
if(!pkws)
{
printf("\nNicht genug freier Speicher verfuegbar");
system("PAUSE");
}
control=pkws;
pkws+=anzahl;
pkws->abbruch=-1;
pkws=control;
for(;ch=='N' || ch=='n';)
{
printf("\nBitte machen sie Eingaben fuer %d Autos",anzahl);
printf("\nBitte machen sie ihre Eingaben");
printf("\nnach dem Syntax name,temp,anzahl zylinder,ps und benzing");
printf("\nzB Audi a3 350.0 4 300 S\n");
for(index=1;pkws->abbruch!=-1;pkws++,index++)
{
fflush(stdin);
printf("\nMachen sie ihre eingabe fuer das %d. Auto\n",index);
gets(pkws->name);
do{scanf(" %f %d %d %c",&pkws->speed,&pkws->zylinder,&pkws->ps,&pkws->gas); } while(getchar()!='\n');
}
pkws=control;
printf("\nSie haben folgende Daten angegeben");
for(pkws=control;pkws->abbruch!=-1;pkws++)
{
printf("\nDie Daten der Autos\n");
printf("Name %s | Tempo %f | Zylinder %d | PS %d | Benzin %c\n\n",pkws->name,pkws->speed,pkws->zylinder,pkws->ps,pkws->gas);
}
printf("\nWenn sie diese Daten in die Datei schreiben wollen druecken sie J\n");
printf("Um die Daten nocheinmal einzugeben druecken sie N ");
fflush(stdin);
scanf("%c",&ch);
pkws=control;
}
file=fopen(name,"a");
if(!file) printf("Konnte Datei nicht oeffnen");
for(pkws=control;pkws->abbruch!=-1;pkws++)
{
fprintf(file,"%s\n",pkws->name);
fprintf(file,"%f\n",pkws->speed);
fprintf(file,"%d\n",pkws->zylinder);
fprintf(file,"%d\n",pkws->ps);
fprintf(file,"%c\n",pkws->gas);
fprintf(file,"\n");
}
pkws=control;
fclose(file);
}
void ausgabe(struct wagen *pointer,struct wagen *control)
{
}
int menu()
{
int choice=0;
printf("***** Car Data 1.0 *****\n\n");
printf("Bitte treffen sie eine Wahl\n\n");
printf("1 - Eine neue Datei zum Speichern von Auto Daten anlegen\n");
printf("2 - Neue Autodaten eingeben und speichern\n");
printf("3 - Vorhandene Auto Daten ausgeben lassen\n");
printf("4 - Eine Datei mit Auto Daten loeschen\n");
printf("\n5- Programm beenden\n\n");
scanf("%d",&choice);
return(choice);
}
void new()
{
FILE *pointer;
char name[10];
fflush(stdin);
printf("\nWie soll die Datei heisen (dateiendung bitte .txt) ");
gets(name);
pointer=fopen(name,"w");
if(!pointer) printf("Konnte Datei nicht anlegen");
else printf("Datei erfolgreich angelegt\n\n");
}
void del()
{
}
|
|
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Schatten: 22.08.2007 23:05.
|
|
22.08.2007 23:01 |
|
|
|
nimm dir doch lieber gleich ne verkettete liste ... da hat man solche speicherprobleme nicht ...
hänge zu den variablen deines structs einen pointer auf ein struct dieses typs
instanziere dein erstes struct, und lasse es befüllen ... sobald du weitere daten bekommst lasse dir weiteren speicher für ein weiteres geben, und gebe dein pointer dafür an denneuen pointer in deinem ersten struct ...
für den nächsten datensatz hängst du den pointer an das vorherige element ...
wenn du den speicher mit calloc anforderst ist er nach der allozierung bereits mit 0 initialisiert. um nun alle elemente der reihe nach anzugrasen kannst du folgende schliefe verwenden:
for(ptr=base;ptr;ptr=ptr->next)
ptr ist der laufende pointer über den du an die daten kommst ... base ist das erste element der kette, und wer hätte es gedacht ... das feld next im struct enthält den pointer aufs nächste struct ...
willst du auch noch in der anderen richtung durch die liste gehen, bekommt dein struct noch einen weiteren pointer, der auf das vorherige struct verweißt ... abbruchbedinung ist auch hierbei die tatsache das dieser pointer beim ersten element der kette null ist ...
ein wunderbar sequentiell itterierbares system
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
22.08.2007 23:51 |
|
|
|
Joa. So in etwa
Du musst darauf achten, dass du den 1. Pointer zu deiner Liste behälst, da du eine einfach verkette Liste aufbaust (du kannst immer nur auf das nächste Objekt zugreifen).
Wenn du den 1. Pointer verwirfst, dann kannst du nicht mehr auf die vorherigen "Objekte" zugreifen.
Außerdem musst du am Ende deiner Eingabe immer den aktuellen Pointer auf den next-Pointer setzen. Ansonsten überschreibst du die angeforderten Pointer und verwirfst sie.
Und du musst noch eine End-Bedingung in deine Liste einbauen.
Das würde ich am besten so regeln, dass du den next-Pointer standartmäßig auf NULL setzt. Wenn kein weiteres Auto angefordert wird, so ist der next-Pointer des letzten "Objekts" NULL, was beim durchlaufen der Liste das Ende signalisiert.
Sprich das hier einfach am Ende der Schleife einfügen (und nicht vergessen den aller ersten Pointer irgendwo abzulegen, damit du den Startpunkt hast!)
code: |
1:
2:
|
pointer_aktuell = pointer_aktuell->pointer_next;
pointer_aktuell->pointer_next = NULL; |
|
Gruß TheImaginator
EDIT: Wenn du lustig bist, dann kannst du noch Suchalgorythmen in deine Struktur einbauen, indem du Zeiger auf Funktionen hinzufügst.
EDIT2: Wenn du das tust, dann kannst du auch gleich C++ lernen
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von TheImaginator: 23.08.2007 12:53.
|
|
23.08.2007 12:47 |
|
|
|
jop, und wo ich die sache einbau weis ich auchschon
bei der ausgabe der daten aus der datei. ich les einfach die daten aus der datei mit fwrite in nen strukt ein, und reservier für jeden strukt bis EOF neuen speicher in schleifenform. dann kann man den strukt beliebig ausgeben/verändern und hat damit ne art "bearbeiten" funktion.
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
23.08.2007 12:51 |
|
|
|
nur stimmen deine pointer dann nicht mehr
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
23.08.2007 13:12 |
|
|
|
frage: wir kann ich mit fwrite den inhalt von strukturariablen in ne datei schrieben, wenn ich nur den pointer auf die strukturvariable hab?
also ich hab mit malloc speicher reserviert für eine strukturvariable und hab jetzt den pointer auf diese.
mit fprintf schreib ich die daten ja einfach so:
code: |
1:
|
fprintf(filepointer,"%s",pointer->inhalt); |
|
aber wie mach ich das mit fwrite?
eig müsste es ja so gehn:
code: |
1:
|
fwrite(*inhalt_von_pointer,sizeof(*pointer),1,file); |
|
das heist doch eig schreibe sizeof(*pointer)(also den ganzen inhalt) des pointers (in dem fall die strukturvariable) einmal in die file die mit dem file* pointer angewählt ist.
...aber dan hat die textdatei folgenden inhalt
" tt Spec=C:\WINDOWS\system32 @ NO_HOST_"
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Schatten: 23.08.2007 15:46.
|
|
23.08.2007 15:44 |
|
|
|
fwrite erwartet als 1. Argument einen Pointer.
code: |
1:
|
fwrite(pointer, sizeof(*pointer), 1, file); |
|
|
|
23.08.2007 16:04 |
|
|
|
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:
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct foobar{
int a,b,c;
char dummy[5];
struct foobar *next;
};
int main () {
struct foobar *test;
FILE *fp;
test=(struct foobar*)calloc(1,sizeof(struct foobar));
test->a=1;
test->b=2;
test->c=3;
memcpy(&test->dummy,"blah",4);
test->next=test;
fp=fopen("c:\\test.dat","wb");
printf("%d\n",fwrite(test,sizeof(struct foobar),1,fp));
fclose(fp);
free(test);
system("pause");
return 0;
}
|
|
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
23.08.2007 16:19 |
|
|
|
Zitat: |
Original von TheImaginator
EDIT: Wenn du lustig bist, dann kannst du noch Suchalgorythmen in deine Struktur einbauen, indem du Zeiger auf Funktionen hinzufügst.
|
|
Warum sollte man die brauchen? Bitte ein Beispiel...
|
|
23.08.2007 17:04 |
|
|
|
nun, man könnte funktionen hinterlegen die vergleiche wischen unterschiedlichen struktur instanzen oder unterschiedlichen struktur typen erlauben, aber dafür braucht man nicht zwingend einen funktionspointer in der instanz... gänzlich entzieht sich mir allerdings warum man algorithmen in eine struktur einbauen sollte ... ein algo arbeitet evtl auf einer struktur, oder hat anhänig von den dingen die er bearbeitet hilfsfunktionen die von der instanz aus referenziert werden (um verschiedene typen zu unterscheiden und anders zu behandeln), aber ich glaube von anwendungsfällen in denen das nötig wird, ist das hier noch weit entfernt ...
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
23.08.2007 17:49 |
|
|
|
kinners, bedenkt ma, ich lern diese sprache erst seit ner woche...
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
23.08.2007 21:13 |
|
|
|
na dann mal ein kleines anschauungs objekt...
ist schnell zusammengezimmert, und vermutlich hats noch versteckte bugs... aber es sollte dir beispielhaft zeigen wie man dynamisch mit speicher umgeht, oder in dateien schreibt und aus ihnen ließt ... es ist selbstverständlich nur eine möglichkeit ...
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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct fahrzeug{
unsigned int preis;
char *name;
unsigned int namelen;
unsigned int leistung;
unsigned int typ; /* 0=pkw 1=lkw 2=zug 3=schiff*/
union{
struct{
unsigned int sitze;
} pkw;
struct{
unsigned int achsen;
unsigned int ladefl;
unsigned int maxgewicht;
} lkw;
struct{
unsigned int schrauben;
unsigned int tiefgang;
unsigned int decks;
}schiff;
struct{
unsigned int laenge;
unsigned int sitzpl;
unsigned int stehpl;
} zug;
}daten;
struct fahrzeug *next;
};
void hr()
{
printf("-----------------------------\n");
}
void show_fahrzeug(struct fahrzeug *ptr)
{
char *typ;
switch(ptr->typ){
case 0:
typ="PKW";
break;
case 1:
typ="LKW";
break;
case 2:
typ="Zug";
break;
case 3:
typ="Schiff";
break;
default:
typ="Unbekannt";
}
hr();
printf("Typ:\t%s\n",typ);
hr();
printf("Daten:\nPreis:\t\t%d\nName:\t\t%s\nLeistung:\t%d\n\n",ptr->preis,ptr->name,ptr->leistung);
switch(ptr->typ){
case 0:
printf("Sitzplaetze:\t%d\n",ptr->daten.pkw.sitze);
break;
case 1:
printf("Achsen:\t\t%d\nLadeflaeche:\t%d\nMaximalgewicht:\t%d\n",ptr->daten.lkw.achsen,ptr->daten.lkw.ladefl,ptr->daten.lkw.maxgewicht);
break;
case 2:
printf("Laenge:\t\t%d\nSitzplaetze:\t%d\nStehplaetze:\t%d\n",ptr->daten.zug.laenge,ptr->daten.zug.sitzpl,ptr->daten.zug.stehpl);
break;
case 3:
printf("Schrauben:\t\t%d\nTiefgang:\t%d\nDecks:\t\t%d\n",ptr->daten.schiff.schrauben,ptr->daten.schiff.tiefgang,ptr->daten.schiff.decks);
break;
}
hr();
}
char* readstring()
{
char *s[2];
char c;
int idx=0,jdx=1,xor=0;
s[0]=(char*)calloc(10,sizeof(char));
while((c=getchar())!='\n')
{
if(idx%10==9)
{/*bevor fragen auftauchen ... das ist mein ersatz für realloc*/
s[xor^1]=(char*)calloc(++jdx*10,sizeof(char));
memcpy(s[xor^1],s[xor],idx);
free(s[xor]);
s[xor]=NULL; /*der form halber*/
xor=xor^1;
}
*(s[xor]+(idx++))=c;
}
s[xor^1]=(char*)calloc(idx+1,sizeof(char));
memcpy(s[xor^1],s[xor],idx);
free(s[xor]);
return s[xor^1];
}
int main () {
struct fahrzeug *ptr,*base,*next;
FILE *fp;
unsigned int num=0;
unsigned int dummy;
char c;
base=(struct fahrzeug*)calloc(1,sizeof(struct fahrzeug));
ptr=base;
next=base;
fp=fopen("c:\\test.dat","rb");
if(fp)
while(1)
{
if(fread(next,sizeof(struct fahrzeug),1,fp)==0)
{
/*es ist ein fehler in der datei, oder es liegen keine weiteren daten vor --- error handling*/
memset(next,0,sizeof(struct fahrzeug));
break;
}
if(next->namelen<1)
{
/*name nicht vorhanden --> nullstring*/
next->name=(char*)calloc(1,sizeof(char));
}
else
{
next->name=calloc(next->namelen+1,sizeof(char));
if(fread(next->name,sizeof(char),next->namelen,fp)==0)
{
free(next->name);
memset(next,0,sizeof(struct fahrzeug));
break;
}
}
next->next=(struct fahrzeug*)calloc(1,sizeof(struct fahrzeug));
next=next->next;
num++;
if(fread(&dummy,sizeof(unsigned int),1,fp)==0)
{
/*es ist ein fehler in der datei --- error handling*/
break;
}
if(dummy!=0xdeadbeef)
{
/*es ist ein fehler in der datei --- error handling*/
break;
}
}
fclose(fp);
if(num>0)
{
printf("Es wurden %d Eintraege gelesen\n",num);
for(;ptr->next;ptr=ptr->next)
show_fahrzeug(ptr);
}
printf("Ein neues Fahrzeug eingeben?(J/N)\n");
c=(char)0x00;
while(c==(char)0x00)
{
scanf("%1[jJnN]",&c);
fflush(stdin);
}
if(c=='j'||c=='J')
{
/*eingabe*/
printf("Name des Fahrzeugs?\n");
next->name=readstring();
next->namelen=strlen(next->name);
fflush(stdin);
printf("Typ waehlen:(0=PKW 1=LKW 2=Zug 3=Schiff)\n");
c=(char)0x00;
while(c==(char)0x00)
{
scanf("%1[0123]",&c);
fflush(stdin);
}
next->typ=(unsigned int)(c-'0');
switch(c)
{
case '0':
printf("PKW gewaehlt.\nGeben Sie mit Leerzeichen getrennt ein: Leistung, Preis, Sitze\n(nur ganze Zahlen ohne Einheiten)\n");
scanf("%d %d %d",&next->leistung,&next->preis,&next->daten.pkw.sitze);
break;
case '1':
printf("LKW gewaehlt.\nGeben Sie mit Leerzeichen getrennt ein: Leistung, Preis, Achsen, Ladeflaeche, Maximalgewicht\n(nur ganze Zahlen ohne Einheiten)\n");
scanf("%d %d %d %d %d",&next->leistung,&next->preis,&next->daten.lkw.achsen,&next->daten.lkw.ladefl,&next->daten.lkw.maxgewicht);
break;
case '2':
printf("Zug gewaehlt.\nGeben Sie mit Leerzeichen getrennt ein: Leistung, Preis, laenge, Sitzplaetze, Stehplaetze\n(nur ganze Zahlen ohne Einheiten)\n");
scanf("%d %d %d %d %d",&next->leistung,&next->preis,&next->daten.zug.laenge,&next->daten.zug.sitzpl,&next->daten.zug.stehpl);
break;
case '3':
printf("Schiff gewaehlt.\nGeben Sie mit Leerzeichen getrennt ein: Leistung, Preis, Schrauben, Tiefgang, Decks\n(nur ganze Zahlen ohne Einheiten)\n");
scanf("%d %d %d %d %d",&next->leistung,&next->preis,&next->daten.schiff.schrauben,&next->daten.schiff.tiefgang,&next->daten.schiff.decks);
break;
}
/*daten erfasst*/
fp=fopen("c:\\test.dat","wb");
dummy=0xdeadbeef;
if(!fp)
{
printf("Datei kann nicht zum schreiben geoeffnet werden.");
}
else
for(ptr=base;ptr;ptr=ptr->next)
{
fwrite(ptr,sizeof(struct fahrzeug),1,fp);
fwrite(ptr->name,sizeof(char),ptr->namelen,fp);
fwrite(&dummy,sizeof(unsigned int),1,fp);
}
}
/*aufräumen*/
for(ptr=base;ptr;)
{
struct fahrzeug *tmp;
tmp=ptr->next;
free(ptr->name);
free(ptr);
ptr=tmp;
}
system("pause");
return 0;
} |
|
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
24.08.2007 00:48 |
|
|
|
sooo...da bin ich wieder
nachdem ich zwei wochen von der ausenwelt abgeschnitten war (router im ar***)
also die zwei wochen habe ich intensievst genutzt um...einfach auf meinem bett zu gammeln...^^
und nach anderthalb wochen gammeln kam mir die idee "hei man könnte wieder ma programmieren"
da es sich bei diesem besagten tag um einen donnerstag handelte musste ich des mittags zeitung austragen. ich verbrachte also die nächsten 2h alleine mit meinen zeitungen und dachte über dies und das nach..und iwann auch übers programmieren. da fiel mir ein, das ich mich ja zuletzt mit dynamischer speicherverwaltung auseinander gesetzt hab. und das das ja eig jetzt sowie erledigt war. struktur wurde dynamisch verwaltet etc wie ein paar beiträge weiter oben ja zu sehen ist. doch auf grund meines nicht zu stillenden ergeizes dachte ich mir, da muss es doch noch was zu verbessern geben. ich dachte also nach und mir fiel ein, das eig das einzig undynamische in dem code wohl oder übel die struktur ist, deren aufbau ja vom endbenutzer in keinerst weise beeinflusst werden kann. ich machte mich also dran und überlegte mir die weiteren zwei stunden eine möglichkeit, wie man das ändern kann. mir viel dann auch ganz spontan eine ein und ich hab das dann ma in insg, 10 arbeitsstunden umgesetzt. was dabei herausgekommen ist sieht man dann da unten....was es macht sollte eig ausreichend kommentiert sein, falls es trotzdem unklar sein sollte, eig macht das prgramm nix anderes als ne struktur zu erstellen mit werten zu füllen und diese wieder auszugeben:
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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
|
/**************************************************************
* Speicherverwaltung.c *
* *
* Verdeutlicht die Arbeit mit dynamischer Speicherverwaltung *
* Erstellt eine Speichervariante ähnlich einer Struktur, *
* Füllt diese mit Werten und gibt diese aus. *
* Die Speicherverwaltung ist dabei wie folgt aufgeteilt: *
* Index-Speicher: *
* ----------- ------------ ----------- *
* |Adresse des|Adresse der |Adresse des| *
* |vorherigen |eigentlichen|nächsten | *
* |Indexteils |Speicher- |Indexteils | *
* | |stelle | | *
* ----------- ------------ ----------- *
* Der Inhalts-Index-Speicher *
* ------- -------- *
* |Art des|Adresse | *
* |Inhalts|des eig.| *
* |i,s,f,c|Inhalts | *
* ------- -------- *
* Inhalt *
* --------------------------------------- *
* |Dem bedarf entsprechend großer Speicher| *
* --------------------------------------- *
**************************************************************/
#include <stdio.h>
#include <limits.h>
#define UP 1
#define DOWN 2
void ausgabe(int *,int *,int*);
void eingabe(int *,int *,int *);
int main()
{
/***************************************************************************************************************
pointer_move: Der Hauptpointer, der sich auf dem Index-Speicher bewegt
pointer_inhalt: Der Pointer, der sich auf dem Inhalts-Index bewegt
pointer_anfang: Verweist auf den Anfang d.h den ersten Eintrag im Index-Speicher
pointer_ende: s.oben nur das er aufs Ende verweist
pointer_int,char,short,float: Die pointer die auf den eig Inhalt zeigen, müssen versch Datentypen haben, da die
Größe der Speicherstelle abhängig ist von dem Typ des Zeigers
pointer_index: Hilfspointer, der zum lesen der Rücksprungadresse benötigt wird.
***************************************************************************************************************/
int *pointer_index,*pointer_inhalt,*pointer_anfang,*pointer_ende,*pointer_move,*pointer_int;
char choice,*pointer_char;
short *pointer_short;
float *pointer_float;
/**********************************************************************************************************************************
Erstellung des Index: Dieser besteht aus X Teilen zu jeweils 3*4Byte. Inhalt der Byteblöcke s.oben
**********************************************************************************************************************************/
pointer_index=malloc(3*(sizeof(int)));
pointer_anfang=pointer_index;
printf("*************************************************************\n");
printf("* 1.Schritt: Struktur anlegen und Elemente erstellen *\n");
printf("*************************************************************\n\n");
for(;;)
{
pointer_move=malloc(3*(sizeof(int)));
if(!pointer_move)
{
printf("\n!Konnte Struktur nicht erstellen!");
return 0;
}
else
{
printf("\nStruktur angelegt.\n");
}
*pointer_move=pointer_index;
pointer_index+=2;
*pointer_index=pointer_move;
/*****************************************************************
Erstellen des Inhalts-Index-Speichers und des Inhalts-Speichers
Anschließendes Verknüpfen zu den Sprungadressen
*****************************************************************/
printf("Welchen Typ soll das Element haben\n");
printf("i - Integer\n");
printf("s - short\n");
printf("f - float\n");
printf("c - char\n\n");
printf("Ihre Wahl ");
do{scanf("%c",&choice);} while(getchar()!='\n');
switch (choice) {
case 'i' : pointer_inhalt=malloc(2*(sizeof(int)));
if(!pointer_inhalt)
{
printf("\n!Konnte Elementindex nicht anlegen!");
return 0;
}
*pointer_inhalt='i';
pointer_int=malloc(sizeof(int));
if(!pointer_int)
{
printf("\n!Konnte Elementspeicher nicht anlegen!");
return 0;
}
pointer_inhalt++;
*pointer_inhalt=pointer_int;
break;
case 's' : pointer_inhalt=malloc(2*(sizeof(int)));
if(!pointer_inhalt)
{
printf("\n!Konnte Elementindex nicht anlegen!");
return 0;
}
*pointer_inhalt='s';
pointer_short=malloc(sizeof(short));
if(!pointer_short)
{
printf("\n!Konnte Elementspeicher nicht anlegen!");
return 0;
}
pointer_inhalt++;
*pointer_inhalt=pointer_short;
break;
case 'f' : pointer_inhalt=malloc(2*(sizeof(int)));
if(!pointer_inhalt)
{
printf("\n!Konnte Elementindex nicht anlegen!");
return 0;
}
*pointer_inhalt='f';
pointer_float=malloc(sizeof(float));
if(!pointer_float)
{
printf("\n!Konnte Elementspeicher nicht anlegen!");
return 0;
}
pointer_inhalt++;
*pointer_inhalt=pointer_float;
break;
case 'c' : pointer_inhalt=malloc(2*(sizeof(int)));
if(!pointer_inhalt)
{
printf("\n!Konnte Elementindex nicht anlegen!");
return 0;
}
*pointer_inhalt='c';
pointer_char=malloc(sizeof(char));
if(!pointer_char)
{
printf("\n!Konnte Elementspeicher nicht anlegen!");
return 0;
}
pointer_inhalt++;
*pointer_inhalt=pointer_char;
break;
default : printf("\n\n!ungueltige Eingabe!\n\n");
return 0;
};
printf("\nElement angelegt");
pointer_move++;
pointer_inhalt--;
*pointer_move=pointer_inhalt;
printf("\nNoch ein Element anfuegen? j/n ");
do{scanf("%c",&choice);} while(getchar()!='\n');
pointer_index=pointer_move;
pointer_index--;
pointer_move--;
if(choice=='n' || choice=='N') break;
}
pointer_move+=2;
pointer_ende=pointer_move;
pointer_move-=2;
/*************************************************************
Abgrasen der einzelnen Index-Speicherteile und umherjagen
Des Index-Inhalts-Pointers sowie der versch. Inhalts Pointer
um die Inhalte mit Daten zu füllen...
*************************************************************/
printf("\n\n*********************************************");
printf("\n* 2.Schritt: Elemente mit Daten fuellen *\n");
printf("*********************************************\n\n");
printf("Ihre erstellte Struktur sieht wie folgt aus: \n");
pointer_move=pointer_anfang;
pointer_move+=2;
pointer_move=*pointer_move;
printf("\n ---------\n");
for(;;)
{
pointer_move++;
pointer_inhalt=*pointer_move;
switch (*pointer_inhalt) {
case 'i' : printf("| integer |");
break;
case 'c' : printf("| char |");
break;
case 'f' : printf("| float |");
break;
case 's' : printf("| short |");
break;
};
printf("\n ---------\n");
pointer_move++;
if(pointer_move==pointer_ende) break;
pointer_move=*pointer_move;
}
eingabe(pointer_move,pointer_anfang,pointer_ende);
ausgabe(pointer_move,pointer_anfang,pointer_ende);
printf("home");
return 0;
}
void eingabe(int *pointer_move,int *pointer_anfang,int *pointer_ende)
{
int *pointer_int,*pointer_inhalt;
char *pointer_char;
float *pointer_float;
short *pointer_short;
pointer_move=pointer_anfang;
pointer_move+=2;
pointer_move=*pointer_move;
for(;;)
{
pointer_move++;
pointer_inhalt=*pointer_move;
printf("\nMachen sie bitte eine Eingabe vom Typ ");
switch (*pointer_inhalt) {
case 'i' : printf("integer\n");
pointer_inhalt++;
pointer_int=*pointer_inhalt;
do{scanf("%d",&*pointer_int); } while(getchar()!='\n');
break;
case 'c' : printf("char\n");
pointer_inhalt++;
pointer_char=*pointer_inhalt;
do{scanf("%c",&*pointer_char); } while(getchar()!='\n');
break;
case 'f' : printf("float\n");
pointer_inhalt++;
pointer_float=*pointer_inhalt;
do{scanf("%f",&*pointer_float); } while(getchar()!='\n');
break;
case 's' : printf("short\n");
pointer_inhalt++;
pointer_short=*pointer_inhalt;
do{scanf("%d",&*pointer_short); } while(getchar()!='\n');
break;
};
pointer_move++;
if(pointer_move==pointer_ende) break;
pointer_move=*pointer_move;
}
printf("\n\n*****************************************");
printf("\n* 3.Schritt: Elemente ausgeben *\n");
printf("*****************************************\n\n");
}
void ausgabe(int *pointer_move,int *pointer_anfang,int *pointer_ende)
{
int *pointer_int,*pointer_inhalt;
char *pointer_char;
short *pointer_short,choice;
float *pointer_float;
printf("Moechten sie die Ausgabe vom Anfang (1) oder vom Ende(2) ");
do{scanf("%d",&choice); } while(getchar()!='\n');
if(choice==UP)
{
pointer_move=pointer_anfang;
pointer_move+=2;
pointer_move=*pointer_move;
}
if(choice==DOWN)
{
pointer_move=pointer_ende;
pointer_move-=2;
}
for(;;)
{
if(choice==DOWN)
{
if(pointer_move==pointer_anfang) break;
}
pointer_move++;
pointer_inhalt=*pointer_move;
switch (*pointer_inhalt) {
case 'i' : pointer_inhalt++;
pointer_int=*pointer_inhalt;
printf("| %d | \n",*pointer_int);
break;
case 'c' : pointer_inhalt++;
pointer_char=*pointer_inhalt;
printf("| %c | \n",*pointer_char);
break;
case 'f' :pointer_inhalt++;
pointer_float=*pointer_inhalt;
printf("| %f | \n",*pointer_float);
break;
case 's' :pointer_inhalt++;
pointer_short=*pointer_inhalt;
printf("| %d | \n",*pointer_short);
break;
};
if(choice==UP) pointer_move++;
if(choice==DOWN) pointer_move--;
if(choice==UP)
{
if(pointer_move==pointer_ende) break;
}
pointer_move=*pointer_move;
}
}
|
|
an was jetzt grade noch gearbeitet wird ist ner datenverabrietung eingebettet in den code und ner *free-routine* um den strukturspeicher am ende wieder freizugeben
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
09.09.2007 01:39 |
|
|
|
Zitat: |
Original von von meinem Compiler, der deinen Code übersetzt hat
foo.c: In function 'main':
foo.c:55: warning: incompatible implicit declaration of built-in function 'malloc'
foo.c:72: warning: assignment makes integer from pointer without a cast
foo.c:74: warning: assignment makes integer from pointer without a cast
foo.c:102: warning: assignment makes integer from pointer without a cast
foo.c:119: warning: assignment makes integer from pointer without a cast
foo.c:136: warning: assignment makes integer from pointer without a cast
foo.c:153: warning: assignment makes integer from pointer without a cast
foo.c:162: warning: assignment makes integer from pointer without a cast
foo.c:185: warning: assignment makes pointer from integer without a cast
foo.c:190: warning: assignment makes pointer from integer without a cast
foo.c:204: warning: assignment makes pointer from integer without a cast
foo.c: In function 'eingabe':
foo.c:220: warning: assignment makes pointer from integer without a cast
foo.c:224: warning: assignment makes pointer from integer without a cast
foo.c:229: warning: assignment makes pointer from integer without a cast
foo.c:234: warning: assignment makes pointer from integer without a cast
foo.c:239: warning: assignment makes pointer from integer without a cast
foo.c:244: warning: assignment makes pointer from integer without a cast
foo.c:250: warning: assignment makes pointer from integer without a cast
foo.c: In function 'ausgabe':
foo.c:269: warning: assignment makes pointer from integer without a cast
foo.c:283: warning: assignment makes pointer from integer without a cast
foo.c:286: warning: assignment makes pointer from integer without a cast
foo.c:290: warning: assignment makes pointer from integer without a cast
foo.c:294: warning: assignment makes pointer from integer without a cast
foo.c:298: warning: assignment makes pointer from integer without a cast
foo.c:308: warning: assignment makes pointer from integer without a cast
|
|
Sieht nicht so gut aus und könnteste noch beheben...
Einheitliches Einrücken würde mir auch gefallen.
Werde mir später mal anschauen, wie du das realisiert hast... ne richtige Struktur scheinst du ja nicht zu nutzen... bin ich mal gespannt.
|
|
09.09.2007 02:34 |
|
|
|
er macht sich wie üblich das leben viel zu schwer ...
er alloziert platz für nen int, und nutzt den dann als pointer ...
er initialisiert seinen speicher nicht ...
er nutzt keine strukturen, sondern hüpft mit pointerarithmetik durch die gegend ... das mag zwar ganz nett sein um den umgang mit pointern zu üben, aber es geht viel einfacher ...
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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct datenvektor_ {
struct datenvektor_ *next;
int typ;
void *data;
} datenvektor;
char* readstring()
{
char *s[2];
char c;
int idx=0,jdx=1,xor=0;
s[0]=(char*)calloc(10,sizeof(char));
while((c=getchar())!='\n')
{
if(idx%10==9)
{/*bevor fragen auftauchen ... das ist mein ersatz für realloc*/
s[xor^1]=(char*)calloc(++jdx*10,sizeof(char));
memcpy(s[xor^1],s[xor],idx);
free(s[xor]);
s[xor]=NULL; /*der form halber*/
xor=xor^1;
}
*(s[xor]+(idx++))=c;
}
s[xor^1]=(char*)calloc(idx+1,sizeof(char));
memcpy(s[xor^1],s[xor],idx);
free(s[xor]);
return s[xor^1];
}
int main () {
datenvektor *base,*ptr;
char typ;
base=(datenvektor*)calloc(1,sizeof(datenvektor));
ptr=base;
while(1)
{
printf("einen (I)nt oder einen (S)tring speichern? (Jedes andere Zeichen zum Beeden)\n");
scanf("%c",&typ);
fflush(stdin);
typ&=223; /*poor mans to_upper_case()*/
if(typ=='I')
{
ptr->data=calloc(1,sizeof(int));
printf("Einen Int bitte:\n");
scanf("%i",(int*)ptr->data);
fflush(stdin);
ptr->next=(datenvektor*)calloc(1,sizeof(datenvektor));
}
else if(typ=='S')
{
printf("Einen String bitte:\n");
ptr->data=(void*)readstring();
ptr->typ=1;
ptr->next=(datenvektor*)calloc(1,sizeof(datenvektor));
}
else
break;
ptr=ptr->next;
}
for(ptr=base;ptr;ptr=ptr->next)
{
if(ptr->data)
switch(ptr->typ)
{
case 0: /*int*/
printf("Ein Int:%d\n",*(int*)ptr->data);
break;
case 1: /*string*/
printf("Ein String:%s\n",(char*)ptr->data);
break;
}
}
for(ptr=base;ptr;)
{
datenvektor *tmp;
tmp=ptr->next;
free(ptr->data);
free(ptr);
ptr=tmp;
}
system("pause");
return 0;
} |
|
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von DarkSquirrel: 09.09.2007 03:28.
|
|
09.09.2007 03:27 |
|
|
|
schau mal... damit du nacher noch wissen kannst was da an einer speicher stelle steht, brauchst du eine art hinweiß, was da abgelegt wurde ... dieser hinweiß ist fest zuzuordnen, bis der speicher nicht mehr benutzt wird ...
die zuordnung zwischen hinweiß und eigentlichen daten, da sie ja fest zusammen gehören, kann man über eine struktur erzeugen ... ein feld sagt dir was es ist, das andere zeigt auf den speicher wo die daten liegen ...
optional kommen da noch parameter zu, die dir etwas über die länge der daten sagen könnten, oder über den verwendungszweck... aber alles in allem gibt es zwischen all diesen daten, die du als hinweise brauchst, und den eigentlichen daten die du speichern willst eine sehr enge bindung ... zu jedem datensatz gibts einen oder mehrere hinweise, die den datensatz beschreiben ...
es ist wohl naheliegend, das was zusammen gehört in einer struktur zu vereinen ... für ein wenig mehr dynamik lassen sich auch unions verwenden ...
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
09.09.2007 19:23 |
|
|
|
jop das is ja alles richtig was du sagst, der hinweis ist in meinem script ja da. du hast eine beliebig(je nach dem wie viele einträge) lange speicherkette(eig die von dir benutzte struktur) zu je 3*4byte(größe einer pointeradresse) das erste ist die adresse zum vorhergegangenen "speicherglied" die mittlere zum eig speicherinhalt(wobei das so eig nicht stimmt) und das letzte die adresse zu dem nächsten speicherglied, welches wiederrum genauso aufgebaut ist.
der mittlere adresseteil verweist wiederrum auf eine speicherkette aus jeweils 2*4Byte. der erste teil speichert dabei die art des eig inhalt d.h. handelt es sich um eine integer zahl (i) um eine shortzahl(s) etc. der zweite teil ist wiederrum eine adresse, die auf den endgütigen datenspeicher verweist, der je nach bedarf 1(char) 2(short) 4(integer) oder 4(float) Bytes groß ist.
aber welche frage ich mir noch stelle ist, wie realisiere ich ne stringeingabe. eine möglichkeit wäre, wiedderrum eine kette von je 2*4Byte anzulegen, wobei der erste teil den wert enthält (A-Z,a-z) und der zweite die adresse zum nächsten stringelement. und bei aufruf wird ein pointer auf das erste gleid in der stringkette gesetzt und klappert dann jedes element ab. das problem das ich dabei habe, ich muss den string buchstabe für buchstabe eingeben lassen. geht das auch anderst?
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Schatten: 09.09.2007 20:19.
|
|
09.09.2007 20:18 |
|
|
|
bezüglich der string eingabe ... schau dir mal meine funktion readstring an ... sie verkettet zwar nicht, aber bietet dir ne möglichkeit strings beliebiger länge einzulesen (auch wenn die performance bei größeren strings nachlässt). eine abwandlung auf verkettete strings ist denkbar einfach geschrieben ...
bezüglich deiner allozierungsversuche für pointer ... es ist ja gut und schön, dass du weißt das ein pointer auf heutigen systemen 32 lang sein kann ... aber wer sagt dir dass dein programm nur auf solchen systemen läuft?
was du eigentlich allozieren willst ist calloc(3,sizeof(void*)) ... damit macht man zwar immernoch die annahme, dass alle pointer typen gleich groß sind (das sind sie in jeder mir bekannten architektur), aber selbst für den fall dass diese annahme verletzt ist, kann man davon ausgehen dass voidpointer als größt möglicher pointer implementiert sind, und du ausreichend platz hast... das ist zwar nicht perfekt, da man stets genau wissen sollte was man da im speicher genau tut, aber es ist besser als sich einen datentyp anzufordern, von dem man annimmt er sei genauso groß ... was passiert wenn ich ein "typedef uint_8 int;" habe? der datentyp int ist dann unfreundliche 8 bit groß ... du bekämst also nur eines von vier pointerbytes darin unter ... heap overflow wir kommen...
was deine vermeidung von structs anbelangt ...
erzähl mir mal was der unterschied ist zwischen deinem ansatz und meinem... mal abgesehen davon dass ich die typenidentifizirung schon auf der ersten ebene mache, und mir so den 2. pointer auf die eigentlichen daten spaare ...
richtig ... ich spare mir deine pointerarithmetik ... das datenformat und die art und weise der speicherung und identifizirung des datentyps sind gleich ... (von der unschönheit mit den längen von pointer und integer mal abgesehen)...und ich habe ebenfalls auf die verkettung in rückwärtsrichtung verzichtet ...
mein code wirkt allerdings irgendwie überschaubarer ... meinste nicht?
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
09.09.2007 22:56 |
|
|
|
joa stimmt schon, weil du den ganzen umstand mit dem pointer hinundher schieben zum großteil nicht hast, da du den speicherindex mit struct-> ansprechen kannst.
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
10.09.2007 15:26 |
|
|
|