malloc Frage

#3677842
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
}
Gast #3677848
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.
Gast #3677855
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 = ...
  ...
}
#3677887
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
}
#3681268
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));
#3734201
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
}
Gast #3734209
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);
> }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren