Dynamischer Vektor
-
Ich habe ein kleines Verständnissproblem, und zwar folgendes. Ich soll aus einem dynamischen Vektor ein Element löschen dieses wird mit dem Parameter n angegeben, z ist die Größe des Vektors (Anzahl der Einträge). Der Prototyp sieht also so aus:
void loesche_Element(int **vektor, int groesse, int n);
jetzt meine Frage, wieso wird der Funktion ein Doppelpointer übergeben und nicht direkt der Pointer auf den Vektor, denn so könnte man doch trotzdem die Werte des Vektors ändern, oder nicht? Rückgabe wäre der neue Vektor ohne das nte Element.
Grüße
-
jetzt meine Frage, wieso wird der Funktion ein Doppelpointer übergeben und nicht direkt der Pointer auf den Vektor, denn so könnte man doch trotzdem die Werte des Vektors ändern, oder nicht?
Das kommt auf die Aufgabenstellung an. Vermutlich sollst du einen neuen Vektor der Größe
groesse-1
anlegen und den Zeiger darauf eben invektor
zurück geben.(Das ganze ist natürlich nicht sehr effizient. Effizienter wäre es, wenn man den Speicher am Ende als Vorrat für spätere Erweiterungen bereithält. So wie es in C++ zB vector macht)
-
Ja also wir sollen wohl einen neuen Vektor mit dem gelöschten Element zurück geben und über realloc den Speicher an den neuen Vector anpassen.
Also definiere ich in der Funktion einen neuen Vector und gebe diesen wieder zurück, bzw. den Pointer darauf?
-
Tarsuinn schrieb:
Ja also wir sollen wohl einen neuen Vektor mit dem gelöschten Element zurück geben und über realloc den Speicher an den neuen Vector anpassen.
Also definiere ich in der Funktion einen neuen Vector und gebe diesen wieder zurück, bzw. den Pointer darauf?
realloc gibt dir ja eine neue Adresse zurück. Die musst du dann ja selbst wieder zurück geben. Daher der Doppelpointer.
-
Ah ok dann hat sich das Problem glaube ich gelöst jetzt muss ich mir nur noch überlegen wie ich den Rest umsetzte, danke schonmal!
-
So hab mal ein wenig probiert aber so ganz haut das noch nicht hin, bekomme am Ende beim realloc immer einen Core Dumped, an was kann das liegen, bzw. wo ist mein Fehler? Die gewünschte Funktion steht weiter oben.
#include <stdio.h> #include <stdlib.h> void delete_nth(int **vector, int size, int n); main() { int*vector; vector = malloc(3 * sizeof(int)); int werte[] = {1, 2, 3}; vector = werte; delete_nth(&vector, 3, 2); } void delete_nth(int **vector, int size, int n) { int *vector_neu = NULL; int neuerVector[size - 1]; vector_neu = neuerVector; int *vector_alt = *vector; int stelle = n - 1; int i = 0; int j = 0; for (i; i < size; i++) { if (i != stelle) { *(vector_neu + j) = *(vector_alt + i); j++; } } *vector = *vector_neu; *vector = (int*)realloc(*vector, (size-1) * sizeof(int)); }
-
Kurz:
int neuerVector[size - 1]; vector_neu = neuerVector; ... *vector = *vector_neu; *vector = (int*)realloc(*vector, (size-1) * sizeof(int));
vector zeigt auf neuerVector und das ist ein statisches Array. Da ist nichts mit realloc.
-
Du kannst kein Array mit realloc nachbehandeln.
Dein Code ist nur C99.
-
Ok danke, dann anderes gefragt wie muss ich das umbauen um in der Funktion das Element zu löschen einen neuen Vector zu erzeugen ohne das Element, dann den Speicher für den neuen Vector verkleinern und diesen dann wieder zurück geben, bzw. den Pointer daruf um ihn außerhalb der Funktion weiter zu verwenden?
-
Mach neuerVector dynamisch.
Lege ein neues Feld an (mit malloc), kopiere die Daten und gib den alten Vector frei.
-
Warum so kompliziert? Du musst dir nur das letzte Element merken. Ein realloc() kopiert dir gleich deinen alten Inhalt in dein neues Feld. Anschließend müssen nur noch alle Elemente ab n+1 um eine Position nach vorne verschoben werden. Und das gemerkte Element wieder an die letzte Stelle geschrieben.
-
Nick Unbekannt schrieb:
Warum so kompliziert? Du musst dir nur das letzte Element merken. Ein realloc() kopiert dir gleich deinen alten Inhalt in dein neues Feld. Anschließend müssen nur noch alle Elemente ab n+1 um eine Position nach vorne verschoben werden. Und das gemerkte Element wieder an die letzte Stelle geschrieben.
Man muss erst die Elemente ab n+1 nach vorne verschieben (memcpy) und darf dann erst realloc benutzen. Nach dem realloc ist das letzte Element ja schon weg!
Zur richtigen Benutzung von realloc siehe: http://www.c-plusplus.net/forum/206606
-
rüdiger schrieb:
Man muss erst die Elemente ab n+1 nach vorne verschieben (memcpy)
Wäre auch eine Variante.
rüdiger schrieb:
Nach dem realloc ist das letzte Element ja schon weg!
deswegen:
Nick Unbekannt schrieb:
Du musst dir nur das letzte Element merken.
...
Und das gemerkte Element wieder an die letzte Stelle geschrieben.
-
Da das Thema schon ein wenig her ist und ich leider immer noch keine funktionierende Lösung habe, wollte ich fragen ob eventuell jemand den Code der ersten Seite so umschreiben kann das es gehen würde. Bräuchte das nur für eine Klausur, und stehe da echt auf dem Schlauch
-
Tarsuinn schrieb:
jetzt meine Frage, wieso wird der Funktion ein Doppelpointer übergeben
Weiß ich auch nicht, wahrscheinlich aus Unkenntnis des Aufgabenstellers über Zeiger und Arrays.
void delete_nth(int *vector, int size, int n); int main() { int werte[] = {1, 2, 3}; printf("\n%d,%d,%d",werte[0],werte[1],werte[2]); delete_nth(werte, 3, 2); printf("\n%d,%d",werte[0],werte[1]); } void delete_nth(int *vector, int size, int n) { /* n ist hier mal 1-basiert! (unüblich!) */ memmove( &vector[n-1],&vector[n],(size-n)*sizeof(int)); }
-
Wutz schrieb:
Tarsuinn schrieb:
jetzt meine Frage, wieso wird der Funktion ein Doppelpointer übergeben
Weiß ich auch nicht, wahrscheinlich aus Unkenntnis des Aufgabenstellers über Zeiger und Arrays.
void delete_nth(int *vector, int size, int n); int main() { int werte[] = {1, 2, 3}; printf("\n%d,%d,%d",werte[0],werte[1],werte[2]); delete_nth(werte, 3, 2); printf("\n%d,%d",werte[0],werte[1]); } void delete_nth(int *vector, int size, int n) { /* n ist hier mal 1-basiert! (unüblich!) */ memmove( &vector[n-1],&vector[n],(size-n)*sizeof(int)); }
Leider müssen wir es mit dem gegebenen Prototyp lösen.
-
void delete_nth(int **vector, int size, int n); int main() { int werte[] = {1, 2, 3}, *p=werte; printf("\n%d,%d,%d",werte[0],werte[1],werte[2]); delete_nth(&p, 3, 2); printf("\n%d,%d",werte[0],werte[1]); return 0; } void delete_nth(int **vectorp, int size, int n) { int *vector = *vectorp; memmove( &vector[n-1],&vector[n],(size-n)*sizeof(int)); }
Ist natürlich total schizophren, aber sollte damit auf dem Niveau des Aufgabenstellers liegen.