Arraygröße aus Dateiangabe initialisieren
-
~fricky schrieb:
pointercrash() schrieb:
Tim schrieb:
b) Warum das ganze nicht transponiert ablegen?
Ein echter Tim- Brocken ... was meinst Du damit? Singen statt in C minor in C#?
er will zeilen mit spalten vertauschen, um weniger pointer zu haben. bei 'ner grossen, quadratischen matrix oder bei mehr als zweidimensionalen arrays ist das aber auch doof.
Ich denke, er meint pointercrash()s Ansatz, d.h. das Arrays manuell zu "flatten" und als eindimensionales Array abzulegen und sich später über Offsets die korrekte Postition zu berechnen eines Elements.
Mit einem Aufruf von malloc() und free() sollte das auch in C zu programmieren sein!
Auch wenn ich hier der Spielverderber sein muß, aber bisher hat kein Versuch, das Problem gelöst. Hier noch mal die Anforderungen:
- die Dimensionen (Höhe, Breite) werden erst zur Laufzeit ermittelt,
- mit diesen Dimensionen soll ein Array mit einem einzigen malloc-Aufruf erzeugt werden, auf das
- mit array[x][y] zugegriffen werden kann (0 <= x < höhe, 0 <= y < breite).
- Die Lösung muß in Ansi-C geschrieben sein.
Der erste gute Ansatz in C setzte vor_raus, daß "spalten" zur Kompilierzeit bekannt ist und verstößt gegen 1).
Der C++ Ansatz erfüllt alle drei Anforderungen, ist aber C++ und verstößt damit gegen 4).
pointercrash()s Ansatz erüllt 1), 2) aber nicht 3).
Happy coding! In meinen Augen nicht möglich, vllt bin ich aber auch einfach nur zu dämlich
-
NDEBUG schrieb:
Auch wenn ich hier der Spielverderber sein muß, aber bisher hat kein Versuch, das Problem gelöst. Hier noch mal die Anforderungen:
- die Dimensionen (Höhe, Breite) werden erst zur Laufzeit ermittelt,
- mit diesen Dimensionen soll ein Array mit einem einzigen malloc-Aufruf erzeugt werden, auf das
- mit array[x][y] zugegriffen werden kann (0 <= x < höhe, 0 <= y < breite).
- Die Lösung muß in Ansi-C geschrieben sein.
Happy coding! In meinen Augen nicht möglich, vllt bin ich aber auch einfach nur zu dämlich
Hab' noch ein Ding gefunden, das bei quadratischen Arrays funktioniert hat, also Höhe = Breite. Da es ein Sonderfall ist, hab' ich's nicht gepostet, magst es haben? (muß es aber noch entmüllen).
-
NDEBUG schrieb:
Der C++ Ansatz erfüllt alle drei Anforderungen, ist aber C++ und verstößt damit gegen 4).
...In meinen Augen nicht möglich...warum sollte in C nicht gehen, was in C++ möglich ist?
-
Hab' noch ein Ding gefunden, das bei quadratischen Arrays funktioniert hat, also Höhe = Breite. Da es ein Sonderfall ist, hab' ich's nicht gepostet, magst es haben? (muß es aber noch entmüllen).
Klar!
warum sollte in C nicht gehen, was in C++ möglich ist?
Wenn du eine Möglichkeit siehst, ein Programm zu schreiben, das die Anforderungen erfüllt. Poste es!
-
NDEBUG schrieb:
Wenn du eine Möglichkeit siehst, ein Programm zu schreiben, das die Anforderungen erfüllt. Poste es!
ungefähr so:
#define TYPE int TYPE **Create2DArrayAsPointerList (int width, int height) { int s, plain; TYPE *a, **b; plain = width * height * sizeof(TYPE); a = malloc (plain + height * sizeof (TYPE*)); if (a == 0) return 0; b = (TYPE**)(a + plain); for (s=0; s<height; s++) b[s] = a + s*height; return b; } ... TYPE **p = Create2DArrayAsPointerList (..., ...); p[x][y] = irgendwas; ...
-
NDEBUG schrieb:
Hab' noch ein Ding gefunden, das bei quadratischen Arrays funktioniert hat, also Höhe = Breite. Da es ein Sonderfall ist, hab' ich's nicht gepostet, magst es haben? (muß es aber noch entmüllen).
Klar!
So, das hat 2004 funktioniert und tut immer noch. Warum es nicht mit abweichenden Dimensionen will, weiß ich momentan nicht, bzw, was man dagegen tun kann. Bin unter Zeitdruck und hab bald wieder die Quengler am Hals
void square(void) { int i, j, back, ad; const int dim = 5; const int zeilen = dim, spalten = dim; int *adresse; int *feld; int **array; feld = malloc( sizeof(int) * zeilen * spalten); if (feld) { back = 0; for (i = 0; i < zeilen; i ++) for (j = 0; j < spalten; j++) feld[i * zeilen + j] = back++; } array = malloc(sizeof(int*) * zeilen); if (array) { for (i = 0; i < zeilen ; i++ ) { adresse = (feld + (spalten * i)); array[i] = adresse; } for (i = 0; i < zeilen; i ++) for (j = 0; j < spalten; j++) back = array[i][j]; } }
-
^^du musst noch die mallocs zusammenschieben.
-
~fricky schrieb:
^^du musst noch die mallocs zusammenschieben.
Ja, ich hab's schon gesehen, Du hängst einfach an, ich hab's auf zwei mallocs verteilt. Ist immer noch weniger, als eine Batterie von mallocs durchzureißen.
Ich hab' damals als frischer C- Wiedereinsteiger so Matrizen gelagert, aber nie wieder genau das Problem gehabt, aber auch heute mag es keine krummen Dimensionen, war ein vertagtes Problem, das nie wieder aktuell geworden ist.
Vielleicht kannst Du in kurzen Worten sagen, was da schiefhängt?
Muß bloß jetzt wieder los, die Gschroppen einschmieren (Kinder haben Windpocken) und im Wohnzimmer fasse ich bei dem Radau eh keinen ruhigen Gedanken. :p
-
Sieht gut aus. Noch nicht getestet, aber was ich nachvollziehen kann, macht es das was verlangt ist. Bis auf eine Kleinigkeit, auch wenn ihc mich irren kann, müßte es nicht so heißen?
~fricky schrieb:
// ... for (s=0; s<height; s++) b[s] = a + s*width; // statt s*height; // ...
pointercrash() dein Listing schau ich mir nachher zu Hause an.
Danke!
-
NDEBUG schrieb:
Bis auf eine Kleinigkeit, auch wenn ihc mich irren kann, müßte es nicht so heißen?
~fricky schrieb:
// ... for (s=0; s<height; s++) b[s] = a + s*width; // statt s*height; // ...
kann sein, hab's nur schnell hingehackt und oberflächlich getestet. diese pointerlisten-sache finde ich sowieso reichlich blödsinnig. sinnlose speicherverschwendung, nur um array[x][y] schreiben zu dürfen.
-
~fricky schrieb:
NDEBUG schrieb:
Bis auf eine Kleinigkeit, auch wenn ihc mich irren kann, müßte es nicht so heißen?
~fricky schrieb:
// ... for (s=0; s<height; s++) b[s] = a + s*width; // statt s*height; // ...
kann sein, hab's nur schnell hingehackt und oberflächlich getestet. diese pointerlisten-sache finde ich sowieso reichlich blödsinnig. sinnlose speicherverschwendung, nur um array[x][y] schreiben zu dürfen.
hey, ich bin anfänger, eig war meine frage nur, ob´s möglich ist... weil ich mir nich ausmalen konnte, ob sowas überhaupt funktioniert
-
TTP schrieb:
hey, ich bin anfänger, eig war meine frage nur, ob´s möglich ist... weil ich mir nich ausmalen konnte, ob sowas überhaupt funktioniert
kein problem, irgendwie bekommt man alles hin.
btw. mein code von da oben^^ ist übrigens ziemlicher mist. zeigt zwar das prinzip, aber es sind viele bugs drin. z.b. kann man den speicher nicht free'n, weil die pointerliste hinten ist.
-
hmm, dann frag ich ma direkt:
mit welchem Code setzt ich das denn jetzt ab besten um? ich hab jetzt die version die "tausend" mal allokiert und free't
-
Kommt auf die Größe des Arrays und deine Anforderungen an. Wenn du unbedingt mit array[x][y] auf die Daten zugreifen möchtest, dann würde ich im Moment noch mit der "klassichen" Methode arbeiten, sonst würde ich auf jedenfall mit pointercrash()s "flattening" Methode arbeiten. Weiterhin ist die Frage, ob du dein Array oft in der Größe ändern mußt. Das würde dann wieder für die Klassische Methode sprechen, da realloc den Inhalt der alten Speicherbereiche mit in die neuen Speicherberieche übernimmt. Mit pointercrash()s Methode müßtest du die Werte manuell wieder richtig anordnen. Und ~frickys Ansatz funzt aber ist eher ein Hack.
Kommt also drauf an!
-
also eigentlich muss ich die größe nur aus einer datei auslesen und dann verwenden. Wärend das programm läuft, wird die größe nicht mehr geändert. die größe wird einmalig bei programm-erststart festgelegt und dann als fix betrachtet
Edit:
die größe beschränkt sich wahrscheinlich auf unter 100 spalten sowie zeilen. Speicherver(sch)wendung sollte da egal sein...2nd Edit:
Anforderung ist eig. nur das es Funktioniert. Wie ist eig. egal und RAM sollten die Testmaschinen auch mehr als genug für das Programm haben
-
NDEBUG schrieb:
Und ~frickys Ansatz funzt aber ist eher ein Hack.
das hier funzt wirklich, stürzt nicht ab, ist kein hack, 'free' geht, usw:
(aber vielleicht findet ihr ja doch noch'n fehler)#include <stdio.h> #include <stdlib.h> typedef long TYPE; TYPE **PointerList (int width, int height) { int s; TYPE *p, **pp; pp = malloc (width * (height * sizeof(TYPE) + sizeof(TYPE*))); if (0 == pp) return 0; p = (TYPE*)((char*)pp + width * sizeof(TYPE*)); for (s=0; s<width; s++) pp[s] = p + s * height; return pp; } #define AX 3 #define AY 109 int main() { int s,l; TYPE **pp = PointerList (AX, AY); if (0 == pp) { puts ("f*ck!!!"); exit (0); } for (s=0; s<AX; s++) for (l=0; l<AY; l++) pp[s][l] = s+l*AX; for (s=0; s<AX; s++) { for (l=0; l<AY; l++) printf ("%03d ", pp[s][l]); puts (""); } free (pp); }
übrigens muss ich meine zweifel an der geschichte etwas relativieren: die pointerlisten-methode hat den vorteil, dass sie eventuell schneller ist, als 'echte' 2d-arrays, weil keine multiplikationen benötigt werden.
-
wofür steht typedef long TYPE; ?
ich möcht ja keine zahlen speichern sondern mein struct "objekt" dann muss ich das TYPE ändern in objekt oder?
Sry, bin gerad etwas verwirrt...
Sprech ich das ding dann auch über pp[x][y] an oder wie?
-
^^richtig. angenommen du hast eine struct:
struct mystruct { int a; double b; };
dann machste einfach:
typedef struct mystruct TYPE;
...und es sollte funzen.
-
okay, ich probier es gleich aus...
nochmal ne zwischen frage:ich hab mein projekt in mehrere header-dateien verteilt. Daher nutz ich die main() nur um die initailiserungs aufrufe der header aufzurufen.
jetzt hab ich gerad so n bisschen das problem, dass ich nicht weiß wie ich das mit dem allokieren und dem free'n machen soll.
ich hab jetzt die funktion speicher_allokieren() und speicher_freigeben() aber ich kann den zeiger der auf den speicher zeigt ja nicht global deklaieren, da die variable ja erst vom programm gesetzt werden muss (also höhe und breite)
wahrscheinlich sinnvoll das allokieren und das freen doch in den main() zu schieben oder?
Ich muss ja aus anderen Funktionen auch noch auf den Array zugreifen könn
-
[cpp]typedef int TYPE;
TYPE **PointerList (int width, int height)
{
int s;
TYPE *p, **pp;pp = malloc (width * (height * sizeof(TYPE) + sizeof(TYPE)));*
if (0 == pp)
return 0;p = (TYPE*)((char*)pp + width * sizeof(TYPE*));
for (s=0; s<width; s++)
pp[s] = p + s * height;return pp;
} [/cpp]Fehlermeldung:
*error C2440: '=' : cannot convert from 'void *' to 'TYPE *'
wieso void? ich versteh die Fehlermeldung gar nicht, langsam verzweifel ich ein bisschen...