Forum: Compiler & IDEs malloc Frage


von Malte I. (maltomat)


Lesenswert?

Hallo Forum

folgendes Problem: ich möchte ein dynamisches, lokales Array (ibuf) 
innerhalb einer anderen Funktion allozieren und das "gefüllte" Array 
dann zurückgeben. So wie im Code unten geht es nicht, denn innerhalb von 
main ist der Speicher wohl nicht alloziert. Aber wie macht man das?

Danke für die Antworten

1
int ReadData(char *inputfile, int *ibuf)
2
{
3
    FILE *stream_in;
4
    int n;
5
6
    stream_in = fopen(inputfile, "rb");
7
    fread(&n, sizeof(int), 1, stream_in);
8
    ibuf = (int *)malloc(n*sizeof(int));
9
    fread(ibuf, sizeof(int), n, stream_in);
10
    fclose(stream_in);
11
12
    return(n);
13
}
14
15
int main()
16
{
17
    int i, n, *ibuf;
18
19
    ibuf = 0;
20
    n = ReadData("test.bin", ibuf);
21
    printf("n=%d\n", n);          //das geht noch..
22
    for(i=0; i<n; i++) {
23
        printf("%d\n", ibuf[i]);  //das nicht
24
    }
25
    free(ibuf);
26
    return(0);
27
}

von asdfg (Gast)


Lesenswert?

>int ReadData(char *inputfile, int *ibuf)

muss

int ReadData(char *inputfile, int **ibuf)


Wenn Du etwas zurückgeben willst, brauchst Du einen
Ptr.
Wenn Du einen Ptr zurückgene willst, deshalb eine
Ptr auf einen Ptr.

von Quack (Gast)


Lesenswert?

Den Puffer hast du korrekt allokiert, aber du gibst den Pointer nicht 
zurueck an den Aufrufer. Die Zuweisung, die du in ReadData machst, ist 
nur lokal gueltig. Du musst entweder eine Referenz auf einen Zeiger 
uebergeben, oder einen Zeiger auf den Zeiger:

int ReadData(char *inputfile, int &*ibuf)
{
  ...
  ibuf = ...
  ...
}

int ReadData(char *inputfile, int **ibuf)
{
  ...
  *ibuf = ...
  ...
}

von Malte I. (maltomat)


Lesenswert?

ok. Und wie rufe ich ReadData dann von main aus auf?

von asdfg (Gast)


Lesenswert?

>ok. Und wie rufe ich ReadData dann von main aus auf?

    n = ReadData("test.bin", &ibuf);

von Malte I. (maltomat)


Lesenswert?

geht leider noch nicht (stürzt bei Zugriff in main ab). So sieht es 
jetzt aus:

1
int ReadData(char *inputfile, int **ibuf)
2
{
3
    FILE *stream_in;
4
    int n;
5
6
    stream_in = fopen(inputfile, "rb");
7
    fread(&n, sizeof(int), 1, stream_in);
8
    *ibuf = (int *)malloc(n*sizeof(int));
9
    fread(ibuf, sizeof(int), n, stream_in);
10
    fclose(stream_in);
11
12
    return(n);
13
}
14
15
16
int main()
17
{
18
    int i, n, *ibuf;
19
20
    ibuf = 0;
21
    n = ReadData("test.bin", &ibuf);
22
    printf("n=%d\n", n);
23
    for(i=0; i<n; i++) {
24
        printf("%d\n", ibuf[i]);
25
    }
26
    free(ibuf);
27
    return(0);
28
}

von Malte I. (maltomat)


Lesenswert?

ok, es geht jetzt. Muss heissen:

fread(*ibuf, sizeof(int), n, stream_in);


Vielen Dank für die Hilfe!

von Harper B. (harper)


Lesenswert?

Malte Ibs schrieb:
>     *ibuf = (int *)malloc(n*sizeof(int));

Du solltest niemals den Rückgabewert von malloc casten.

- Der von malloc gelieferte type void* wird vom C-Compiler problemfrei 
implizit in jeden anderen Pointer-Type konvertert.
- Jeder Cast kann Fehler verdecken, die ohne Cast vom Compiler durch ein 
Diagnostic Message angezeigt worden wäre.

Beispiel:
1
#include <malloc.h>
2
3
#define TYPE int
4
5
TYPE var = (TYPE)malloc(sizeof(TYPE));

von us73 (Gast)


Lesenswert?

Malte Ibs schrieb:
> *ibuf = (int *)malloc(n*sizeof(int));

Und vielleicht solltest Du auch noch den Rückgabewert von malloc prüfen, 
bevor Du ihn blindlings benutzt. Da kann schon auch mal NULL zurück 
gegeben werden.

von Malte I. (maltomat)


Lesenswert?

Hallo,

noch mal vielen Dank für die Lösung meines Problems und die Tips.

Nun möchte ich das ganze mit einem zweidimensionalen Array machen (falls 
das ähnlich elegant geht). Ich kriegs aber nicht hin. Hier ist die 
"Arbeitsversion" des Codes mit Fragezeichen überall dort, wo ich nicht 
weiterkomme.

1
int ReadData(char *inputfile, int ???ibuf, int *ny)
2
{
3
    FILE *stream_in;
4
    int i, nx, ny1;
5
6
    stream_in = fopen(inputfile, "rb");
7
    fread(&nx, sizeof(int), 1, stream_in);
8
    fread(&ny1, sizeof(int), 1, stream_in);
9
    *ny = ny1;
10
11
    ?ibuf = malloc(nx * sizeof(int*));
12
    for (i=0; i<nx; i++){
13
          ?ibuf[i] = malloc(ny1 * sizeof(int));
14
    }
15
16
    for (i=0; i<nx; i++){
17
        fread(?ibuf[i], sizeof(int), ny1, stream_in);
18
    }
19
    fclose(stream_in);
20
    return(nx);
21
}
22
23
24
int main()
25
{
26
    int i, j, nx, ny, **ibuf;
27
28
    nx = ReadData("test.bin", ?ibuf, &ny);
29
30
    for (i=0; i<nx; i++){
31
        for (j=0; j<ny; j++){
32
            printf("%d ", ibuf[i][j]);
33
        }
34
        printf("\n");
35
    }
36
37
    for (i=0; i<nx; i++){
38
        free(ibuf[i]);
39
    }
40
    free(ibuf);
41
42
    return(0);
43
}

von Rolf Magnus (Gast)


Lesenswert?

Malte Ibs schrieb:
> Hallo,
>
> noch mal vielen Dank für die Lösung meines Problems und die Tips.
>
> Nun möchte ich das ganze mit einem zweidimensionalen Array machen (falls
> das ähnlich elegant geht).

Geht es nicht. Es gibt da mehrere Möglichkeiten, so etwas zu erreichen, 
aber elegant ist das alles nicht. Du hast aber mit einem Array aus 
Pointern einen guten Ansatz gewählt.

  int ReadData(char *inputfile, int ***ibuf, int *ny)
> {
>     FILE *stream_in;
>     int i, nx, ny1;
>
>     stream_in = fopen(inputfile, "rb");
>     fread(&nx, sizeof(int), 1, stream_in);
>     fread(&ny1, sizeof(int), 1, stream_in);
>     *ny = ny1;
>
      *ibuf = malloc(nx * sizeof(int*));
>     for (i=0; i<nx; i++){
          (*ibuf)[i] = malloc(ny1 * sizeof(int));
>     }
>
>     for (i=0; i<nx; i++){
          fread((*ibuf)[i], sizeof(int), ny1, stream_in);
>     }
>     fclose(stream_in);
>     return(nx);

return ist übrigens keine Funktion. Da braucht man keine Klammern:

      return nx;

> }
>
> int main()
> {
>     int i, j, nx, ny, **ibuf;
>
      nx = ReadData("test.bin", &ibuf, &ny);
>
>     for (i=0; i<nx; i++){
>         for (j=0; j<ny; j++){
>             printf("%d ", ibuf[i][j]);
>         }
>         printf("\n");
>     }
>
>     for (i=0; i<nx; i++){
>         free(ibuf[i]);
>     }
>     free(ibuf);
>
>     return(0);
> }

von Malte I. (maltomat)


Lesenswert?

Besten Dank, das klappt!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Btw:

Harper Blues schrieb:

> #include <malloc.h>

Nein, seit 1989 nicht mehr so.  <stdlib.h> ist die zuständige
Headerdatei.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.