FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Allgemeines

Queue in C mit folgendem struct

Queue in C mit folgendem struct 2012-01-21 01:12
Anonymer User
Hi,

ich will einen neuen Datentyp "Queue" in C schreiben und hab so manche probleme.
Irgendwie schaffe ich es die Elemente des Queues nacheinander auszugeben. Auch die Speicherallokation beim dynamischen Array klappt nicht wirklich. Kann mir jemand weiterhelfen?

Quellcode: http://codepad.org/OulOyLQN

RE: Queue in C mit folgendem struct 2012-01-21 04:03
Muelli
na, das sieht doch ein Blindermit nem Holzauge:
q = (Queue *) realloc (*q, sizeof(q*)*2);

sizeof(q*) hast du bestimmt nicht gemeint. Vrmtl eher sowas wie sizeof(*q) :-)

RE: Queue in C mit folgendem struct 2012-01-21 04:05
Muelli
und realloc (*q, …) sieht auch komisch aus. Muesste bestimmt realloc (q, …) sein.

RE: Queue in C mit folgendem struct 2012-01-21 10:21
Vollkorn
Wenn ich das richtig sehe, dann wirst du mit realloc so immer noch nicht glücklich.

sizeof(*q) wird dir nämlich die Größe des Elementes an der Stelle wo der Pointer hinzeigt geben. Und dort ist ein struct vom Typ Queue, dessen Größe sich ja nicht ändert, auch wenn das in einem alloziiertem, größeren Speicherbereich liegt. Was du vermutlich machen möchtest ist etwas wie:

q = (Queue *) realloc (q, 2 * q->queuesize * sizeof(*q));

RE: Queue in C mit folgendem struct 2012-01-21 10:44
Anonymer User
Ja sehe schon, danke. Beim Kompilieren gabs keine Fehler. Ich weiss irgendwie nicht wie man den Queue jetzt printet.

/* print the contents of <*q> on screen */
void queue_print(const Queue *q)
{
int i;
for(i = q->enqueueindex+1; i <= q->dequeueindex; i++)
{
//printf("%d", i);
printf("%d \n", q->queuespace);
}
}

gibt er die falschen Sachen aus. Im struct ist queuespace als unsigned long int definiert. Kann es daher kommen?
Meine idee war, nur die Elemente auszugeben, die vorhanden sind, und nicht die unbelegten Plätze.

RE: Queue in C mit folgendem struct 2012-01-21 11:59
Vollkorn
Moment, queuespace ist als int* definiert.
Wo du bei großen oder negativen Werten in Probleme kommst ist, dass dein i ein int ist, die Indizes aber unsigned longs.
Aber all das ist m.E. gar nicht das Problem hier, sondern, dass du noch nicht verstanden hast wie die Queue funktionieren soll.

Es gibt einen Struct. Dieser enthält ein int Array Queuespace. Queuespace wird bei Bedarf vergrößert. Du hast aber versucht den Speicher des gesamten Queue Objektes zu realloziieren. Ich sehe weder ein malloc, noch ein realloc für den Speicher deiner Queue-Elemente in Queuespace, d.h. du schreibst die ganze Zeit in irgendwelche Speicherbereiche und liest auch wieder aus denen heraus wo irgendwelche anderen Daten liegen.

Noch ein Detail:

free(q->queuespace);

Hier möchtest du free[](q->queuespace); nutzen. Die [] sorgen dafür, dass nicht nur das Element auf das der Pointer queuespace zeigt freigegeben wird, sondern der gesamte Speicher des Arrays.

RE: Queue in C mit folgendem struct 2012-01-21 12:05
Fred
Hier möchtest du free[](q->queuespace); nutzen. Die [] sorgen dafür, dass nicht nur das Element auf das der Pointer queuespace zeigt freigegeben wird, sondern der gesamte Speicher des Arrays.
Du verwechselst C mit C++. In C++ gibt es eine Unterscheidung zwischen delete und delete[], in C gibt es dagegen nur free.

RE: Queue in C mit folgendem struct 2012-01-21 12:38
Anonymer User
@Vollkorn: Könntest du vllt ein Beispiel geben? Wie ich es verstanden habe weist malloc einen festen Speicher zu, und realloc erweitert diesen Speicher (z.B. bei Listen).
Wo soll realloziert werden? Ist mein malloc für die Queue richtig?

RE: Queue in C mit folgendem struct 2012-01-21 12:41
Fred
Dein struct besteht aus 5 Variablen, in queue_new initialisierst Du aber nur 4 davon. Da fehlt noch sowas wie:
queue->queuespace = malloc(queuesize * sizeof(Queueelement));

RE: Queue in C mit folgendem struct 2012-01-21 12:58
Anonymer User
/* The following function resizes the queue by doubling the space reservoir  */
void queue_double_size(Queue *q)
{
// Vorhandener Speicher des Queues wird verdoppelt
q = (Queue *) realloc (*q, sizeof(q*)*2);
// Zu beachten ist, dass die Elemente nach hinten verschoben werden muessen
// damit keine "Loch" entsteht
}

Danke. Hab meinen Fehler eingesehen. Muss ich den Queue reallozieren. Ist das so richtig oder zusätzlich noch den queuespace reallozieren?

RE: Queue in C mit folgendem struct 2012-01-21 12:59
Anonymer User
Korrektur:

/* The following function resizes the queue by doubling the space reservoir  */
void queue_double_size(Queue *q)
{
// Vorhandener Speicher des Queues wird verdoppelt
q = (Queue *) realloc (q, 2 * q->queuesize * sizeof(*q));  // korrigiert
// Zu beachten ist, dass die Elemente nach hinten verschoben werden muessen
// damit keine "Loch" entsteht
}

RE: Queue in C mit folgendem struct 2012-01-21 13:03
Fred
Du musst ausschließlich q->queuespace realloziieren (was für ein Wort), nicht q selber! Du brauchst ja nicht plötzlich mehr Variablen in q, die 5 reichen nach wie vor aus. (Eine Veränderung von q würde der Aufrufer auch gar nicht bemerken, weil der Zeiger ja per Wert übergeben wird.)

RE: Queue in C mit folgendem struct 2012-01-21 13:14
Anonymer User
Das obige habe ich durch:

q = realloc (q->queuespace, 2 * sizeof(*q->queuespace));

ersetzt. Richtig so?

RE: Queue in C mit folgendem struct 2012-01-21 13:15
Anonymer User
Korrektur: q->queuespace = realloc (q->queuespace, 2 * sizeof(*q->queuespace));

RE: Queue in C mit folgendem struct 2012-01-21 13:18
Fred
Nein, sizeof(*q->queuespace) ist gleich sizeof(int), damit wirst Du nicht glücklich werden. Wozu hast Du denn die Variable queuesize?
q->queuesize *= 2; q->queuespace = realloc(q->queuespace, q->queuesize * sizeof(Queueelement));

RE: Queue in C mit folgendem struct 2012-01-21 13:25
Anonymer User
Ok danke. Die neuen Speicherplätze werden jetzt hinten drangehängt richtig? Wenn ja, dann muss ich doch alle Elemente nach hinten verschieben und zwar ab queuesize-1?

RE: Queue in C mit folgendem struct 2012-01-21 13:27
Fred
Hm, könnte sein. Wieso fängt Deine Queue überhaupt hinten an und nicht vorne?

RE: Queue in C mit folgendem struct 2012-01-21 13:29
Vollkorn
Du verwechselst C mit C++. In C++ gibt es eine Unterscheidung zwischen delete und delete[], in C gibt es dagegen nur free.

Oh, danke. Bin ja eher C++-Mensch und habe dann aus der Hüfte geschossen :/

@anonym: Genau das was Fred dir gerade erklärt hat meinte ich auch :)

RE: Queue in C mit folgendem struct 2012-01-21 13:30
Anonymer User
Hmmm. Dachte, dass es besser wäre wegen dem FIFO-Charakter, sonst entstehen vorne die "Löcher" wenn man "dequeuen" möchte.

RE: Queue in C mit folgendem struct 2012-01-21 13:31
Fred
Löcher entstehen so oder so, egal ob Du vorne oder hinten anfängst. Das ganze soll ein zyklisches Array sein, oder?

RE: Queue in C mit folgendem struct 2012-01-21 13:35
Anonymer User
zirkuläres Array sollte identisch zu zyklisches Array denke ich. Hab aber keine Ahnung was damit gemeint ist.

RE: Queue in C mit folgendem struct 2012-01-21 13:36
Fred
Mal doch mal auf, wie das Array aussehen soll, wenn Du 5 Elemente einfügst und anschließend 3 entfernst. Wo stehen dann die verbliebenen 2 Elemente?

Und dann füg mal so viele Elemente ein, dass Du über den Rand hinausläufst und am anderen Rand wieder anfängst. Das ist ein zyklisches/zirkuläres/whatever Array.

RE: Queue in C mit folgendem struct 2012-01-21 13:40
Anonymer User
queue = queue_new(5);
queue_enqueue(queue, 1);
queue_enqueue(queue, 2);
queue_enqueue(queue, 3);
queue_enqueue(queue, 4);
queue_enqueue(queue, 5);

Array = [5 4 3 2 1]

queue_dequeue(queue);
queue_dequeue(queue);

Array [5 4 3]

RE: Queue in C mit folgendem struct 2012-01-21 13:42
Anonymer User
queue = queue_new(5);
queue_enqueue(queue, 1);
queue_enqueue(queue, 2);
queue_enqueue(queue, 3);
queue_enqueue(queue, 4);
queue_enqueue(queue, 5);

Array = [5 4 3 2 1]

queue_dequeue(queue);
queue_dequeue(queue);
queue_dequeue(queue);

Array [5 4]

RE: Queue in C mit folgendem struct 2012-01-21 13:43
Fred
Arrays werden nicht auf magische Weise kleiner. Das hat immer noch die Größe 5, aber Du benutzt nur einen Ausschnitt daraus.

[5 4 x x x]

Jetzt füg bitte noch mal das Element 6 ein.

RE: Queue in C mit folgendem struct 2012-01-21 13:46
Anonymer User
Ja richtig gar nicht bedacht. Wenn es vollläuft dann man etwas entfernt, müssen alle elemente um die anzahl der gelöschten Elemente-1 verschoben werden.

RE: Queue in C mit folgendem struct 2012-01-21 13:48
Fred
Nein, bei einem zirkulären Array brauchst Du nichts zu verschieben! Ansonsten hätte dequeue ja lineare Komplexität. Du klebst die beiden Enden einfach gedanklich aneinander und hast dann einen Kreis.

Ich sehe gerade, das hast Du in den Zeilen 105 bis 115 und 130 bis 136 ja auch schon korrekt implementiert.

RE: Queue in C mit folgendem struct 2012-01-21 13:54
Anonymer User
Ach so. Ich bin davon ausgegangen wenn es leer ist. Das deckt ja auch das was du meintest ab.

RE: Queue in C mit folgendem struct 2012-01-21 20:36
Anonymer User
Wenn ich mit den Werten im main fülle wird wegen dem zyklischen Array alte quesize-1 gefüllt und nicht die neue qeuesize-1…