Speicherverwaltung Probleme

01/22/2017 12:35 KwPJagTqzqC3#1
Moin Leute,

wir haben an der Uni jetzt mit C angefangen und ich benötige Hilfe bei einer kleinen Aufgabe. Es wäre nice wenn mir jemand per Skype helfen könnte und evtl. ein paar Fragen klären könnte. GGF. gegen kleine Bezahlung.

Die Aufgabe sind absolute Basics, also sollten kaum ein Problem für jemand von euch sein.

Grüße Alex
01/22/2017 13:06 chrisyou#2
Was hält dich davon ab, die Fragen öffentlich zu posten, sodass möglist viele darauf antworten können?
01/22/2017 13:55 KwPJagTqzqC3#3
Quote:
Originally Posted by chrisyou View Post
Was hält dich davon ab, die Fragen öffentlich zu posten, sodass möglist viele darauf antworten können?
Eigentlich nichts :)

[Only registered and activated users can see links. Click Here To Register...]
01/22/2017 14:39 Mikesch01#4
Ok und wie können wir dir helfen, außer die komplette Aufgabe für dich zu lösen? :)
01/22/2017 14:57 KwPJagTqzqC3#5
Quote:
Originally Posted by Mikesch01 View Post
Ok und wie können wir dir helfen, außer die komplette Aufgabe für dich zu lösen? :)
Das ist eine gute Frage. Ich verstehe dieses ganze System mit der Speicherreservierung nicht, also mit z.b. malloc(9) reserviere ich mir im Speicher ja 9 Werte, die nicht überschrieben werden können. Aber wie genau verwendet man die, bzw wie gehe ich damit um?

Wir hatten bisher nur Java gelernt und daher verwirrt mich das ganze in C jetzt ein wenig. :confused:

Bin ich mit sowas:
int * p = (int*)malloc(8 * sizeof(int));
Schon mal auf dem richtigen Weg? :D
01/22/2017 15:06 Mikesch01#6
Und jetzt lernt ihr ja eben C :) In deinem Skript von der Uni müsstest du ja sicherlich etwas dazu an Informationen haben.

Es gibt eine nette Dokumentation mit Beispielen. Vielleicht hilft sie dir ein bisschen:
[Only registered and activated users can see links. Click Here To Register...]

Malloc reserviert dir einen Speicherbereich im Heap um die angegebene Anzahl an Bytes und gibt dir einen Zeiger/Pointer auf die erste Speicherstelle zurück.

Nehmen wir an, du willst 3 int Werte abspeichern. Ein int sind typischerweise 4 Byte (die tatsächliche Größe kann mittels sizeof() ermittelt werden). Nun reservierst du dir 3 * 4 Byte = 12 Byte im Heap über:
Code:
int *meineIntWerte = malloc(3 * sizeof(int)); // entspricht 3 * 4 Byte
Auf die Werte kannst du wie ein Array zugreifen. Angefangen mit dem Index 0.

Bsp:
Code:
meineIntWerte[0] = 12; // erstes int wird nun mit 12 belegt
Auslesen geht dann genauso einfach:
Code:
printf("Erstes int: %d", meineIntWerte[0]); // gibt nun 12 aus
Du kannst ja gerne noch schreiben, wo du Probleme hast, nachdem du es mal ausprobiert hast ;) Man kann sicherlich irgendwie weiterhelfen, ohne die tatsächliche Lösung anzugeben :)
01/22/2017 15:07 chrisyou#7
Quote:
Originally Posted by EinEpischerApfel View Post
Das ist eine gute Frage. Ich verstehe dieses ganze System mit der Speicherreservierung nicht, also mit z.b. malloc(9) reserviere ich mir im Speicher ja 9 Werte, die nicht überschrieben werden können. Aber wie genau verwendet man die, bzw wie gehe ich damit um?

Wir hatten bisher nur Java gelernt und daher verwirrt mich das ganze in C jetzt ein wenig. :confused:
Richtig, malloc() reserviert Speicher.

Dabei erwartet malloc() als Parameter den für die Variable zu reservierenden Speicherraum.
Die Funktion gibt einen Zeiger auf den reservierten Speicherraum zurück.
Da die Größe von Integern mitunter systemabhängig ist, empfiehlt sich hier das Schlüsselwort sizeOf.
Um Speicher für deine Integer zu reservieren eignet sich also:
Code:
  int* a;
  a = (int*) malloc(sizeof(int));
Das ganze lässt sich z.B. so verifizieren:
Code:
printf("%d\n",sizeof(*a));
Gibt bei mir eine Größe von 8 Byte aus.

Hast du denn mit dem eigentlichen Problem schon angefangen, zeig doch mal, was du bisher hast.
01/22/2017 15:13 KwPJagTqzqC3#8
Danke für die beiden Antworten von euch.
Bin jetzt so weit:

PHP Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    
int * array = (int*)malloc(sizeof(int));
    return 
0
    
    realloc
(array);
    
printf("Reverse vom Array ist: %d\n", array);
    
}

void realloc(int*array)
{
    
int ijlentemp;
    
i=j=len=temp=0;
    
    
     for (
i=0j=len-1i<=ji++, j--)
    {
        
temp=array[i];
        array[
i]=array[j];
        array[
j]=temp;
    }

Da fehlt aber halt noch einiges und es ist bestimmt auch noch einiges falsch. Z.b. fehlt noch, wie ich dann genau die Array Länge rausbekommen und als len abspeichere und wie ich den Speicher mit free wieder freigebe
01/22/2017 15:26 Devsome#9
#moved
01/22/2017 15:48 warfley#10
Es gibt bereits eine Funktion realloc welche den Speicherbereich vergrößert bzw verkleinert. Was deine Realloc da macht verstehe ich nicht so ganz.

Realloc verwendest du z.B. so
Code:
int *arr;

// 8 elemente im array
arr = malloc(8 * sizeof(int));

// befallen
for (int i = 0; i<8; i++) arr[i] = i;

//vergrößern auf 16 elemente
arr = realloc(arr, 16 * sizeof(int));

//füllen
for (int i = 8; i<16; i++) arr[i] = i;

// alle 16 elemente ausgeben
for (int i = 0; i<16; i++) printf("%d", arr[i]);
Als Tipp, effizient wäre wenn du den Puffer immer verdoppeln würdest sobald der platz voll ist.
01/22/2017 15:51 KwPJagTqzqC3#11
Quote:
Originally Posted by warfley View Post
Es gibt bereits eine Funktion realloc welche den Speicherbereich vergrößert bzw verkleinert. Was deine Realloc da macht verstehe ich nicht so ganz.

Realloc verwendest du z.B. so
Code:
int *arr;

// 8 elemente im array
arr = malloc(8 * sizeof(int));

// befallen
for (int i = 0; i<8; i++) arr[i] = i;

//vergrößern auf 16 elemente
arr = realloc(arr, 16 * sizeof(int));

//füllen
for (int i = 8; i<16; i++) arr[i] = i;

// alle 16 elemente ausgeben
for (int i = 0; i<16; i++) printf("%d", arr[i]);
Als Tipp, effizient wäre wenn du den Puffer immer verdoppeln würdest sobald der platz voll ist.
Ah okay das ist praktisch, ich hab meine realloc Funktion falsch benannt. Das ist die Funktion, die das Array dann invertiert wieder ausgeben soll.
Hast du ne Idee wie ich das genau bei mir einbauen muss? Sieht bisher so aus:
PHP Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    
int * array = (int*)malloc(sizeof(int));
    return 
0;

    
invert(array);
    
printf("Reverse vom Array ist: %d.\n", array);

}

void invert(int* array)
{
    
int ijlentemp;
    
i=j=len=temp=0;


     for (
i=0j=len-1i<=ji++, j--)
    {
        
temp=array[i];
        array[
i]=array[j];
        array[
j]=temp;
    }

01/22/2017 15:59 Mikesch01#12
Tag.

Mit "realloc" ist die integrierte C-Funktion gemeint: [Only registered and activated users can see links. Click Here To Register...]

In deinem Programm fehlt die Eingabe der Zahlen.

So könnte dein Programm grob strukturiert sein:
Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i;

    // Speicher anfordern
    int *array = (int*)malloc(8 * sizeof(int));
    
    // Zahlen einlesen
    /* Deine Aufgabe hier ist es die Zahlen einzulesen bis man fertig ist. 
        Die Anzahl der Eingaben kann sich über mehr als 8 int-Werte strecken 
        und somit muss der Speicherbereich deines Arrays mittels realloc 
        entsprechend erhöht werden */

    // Zahlen rückwärts ausgeben
    printf("Rückwärts: ");
    for(i = (sizeof(*array) / sizeof(int)) - 1; i >= 0; i--) { // Größe von Array geteilt int-Größe = Anzahl der Elemente im Array; 1 abgezogen wegen Array Index-Verschiebung
        printf("%d", array[i]);
    }
    printf("\n");

    // Array wieder freigeben
    free(array);
    
    return 0;
}
01/22/2017 16:00 warfley#13
Quote:
Originally Posted by EinEpischerApfel View Post
Ah okay das ist praktisch, ich hab meine realloc Funktion falsch benannt. Das ist die Funktion, die das Array dann invertiert wieder ausgeben soll.
Hast du ne Idee wie ich das genau bei mir einbauen muss? Sieht bisher so aus:
PHP Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    
int * array = (int*)malloc(sizeof(int));
    return 
0;

    
invert(array);
    
printf("Reverse vom Array ist: %d.\n", array);

}

void invert(int* array)
{
    
int ijlentemp;
    
i=j=len=temp=0;


     for (
i=0j=len-1i<=ji++, j--)
    {
        
temp=array[i];
        array[
i]=array[j];
        array[
j]=temp;
    }

Ja ich wüsste schon was du machen müsstest, aber damit würde ich dir ja den spaß verderben es selbst raus zu finden.

Aber soviel als tipp, ein return in der Main beendet das Programm sofort. Außerdem benötigst du am ende noch ein free um den Speicher des arrays wieder frei zu geben
Code:
 arr = malloc(...);

// Zeugs mit arr machen

// wieder freigeben
free(arr);
01/22/2017 16:24 Beni#14
Noch nen Tipp: Nen Array übergibt man über den Pointer auf das erste Element(hast du schon gemacht) und als zweites gibt man die Anzahl der Elemente an, damit deine Schleife weiß, wann Schluss ist. Aktuell ist bei dir len=0 und es soll von i=0 bis len=-1 laufen... geht nicht so ganz. Sollte dir auch einige Error's throwen. Außerdem hast du keinen Prototypen deiner Funktion angegeben, was in C notwendig ist. Er kommt "von oben" nach unten und sieht "invertiere" aber hat den Funktionskopf noch nie gesehen, also weiß er (der compliler) auch nicht ob du die funktion richtig aufgerufen hast.. denke das sollte ein weiterer Fehler sein.

-> void invert(int *array, int count);

^wäre ein Beispiel für einen Prototypen. (Der kommt vor deine Main)
01/22/2017 17:38 KwPJagTqzqC3#15
Quote:
Originally Posted by Mikesch01 View Post
Tag.

Mit "realloc" ist die integrierte C-Funktion gemeint: [Only registered and activated users can see links. Click Here To Register...]

In deinem Programm fehlt die Eingabe der Zahlen.

So könnte dein Programm grob strukturiert sein:
Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i;

    // Speicher anfordern
    int *array = (int*)malloc(8 * sizeof(int));
    
    // Zahlen einlesen
    /* Deine Aufgabe hier ist es die Zahlen einzulesen bis man fertig ist. 
        Die Anzahl der Eingaben kann sich über mehr als 8 int-Werte strecken 
        und somit muss der Speicherbereich deines Arrays mittels realloc 
        entsprechend erhöht werden */

    // Zahlen rückwärts ausgeben
    printf("Rückwärts: ");
    for(i = (sizeof(*array) / sizeof(int)) - 1; i >= 0; i--) { // Größe von Array geteilt int-Größe = Anzahl der Elemente im Array; 1 abgezogen wegen Array Index-Verschiebung
        printf("%d", array[i]);
    }
    printf("\n");

    // Array wieder freigeben
    free(array);
    
    return 0;
}
Okay den Teil in der Mitte sollte ich hinkriegen, ich schau mal :D

Edit:
In Java bswp. würde ich das halt irgendwie so lösen: while (!StdIn.IsEmpty).....
Gibts da eine ähnliche Funktion zu auch in C?