Forum: PC-Programmierung [C] flexibles Array Memeber in struct initialisieren / memcpy


von Peter L (Gast)


Lesenswert?

Hallo,

ich habe ein struct welches ein float Array flexibler länge beinhalten 
soll. Dieses struct möchte ich anschließend mit Werten befüllen.

Kann mir jemand sagen, was ich falsch mache? Das float-Array wird 
offensichtlich nicht korrekt mit Werten initialisiert.
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
struct data{ 
6
   int data_id; // irgendeine Variable
7
   int a_size;
8
   char vals[]; // FAM
9
}; 
10
11
struct data *createData(struct data *s, int id, int a_size, float a[]) { 
12
    s = malloc( sizeof(*s) + sizeof(float) * a_size); 
13
    s->data_id = id;
14
    s->a_size = a_size;
15
    memcpy(s->vals, a, sizeof(float) * a_size); 
16
    return s; 
17
} 
18
19
void printData(struct data *s){ 
20
    printf("Data_id : %d\n", s->data_id);
21
    int i;
22
    for ( i=0 ; i<s->a_size ; i++){
23
      printf("%f, ",s->vals[i]);
24
    }
25
    printf("\n");
26
} 
27
int main(void) {
28
  float A[] = {1.0, 7.5, 9.3};
29
  float B[] = {2.0, 2.8, 3.0, 5.5};
30
  struct data *s1 = createData(s1, 523, 3, A);
31
  struct data *s2 = createData(s2, 206, 4, B);
32
  printData(s1);
33
  printData(s2);
34
  return 0;
35
}

Ergibt
1
Data_id : 523
2
0.000000, 0.000000, 0.000000, 
3
Data_id : 206
4
0.000000, 0.000000, 0.000000, 0.000000,

https://ideone.com/rsxhaP

Besten Dank,

Peter

von Thomas W. (goaty)


Lesenswert?

struct data *s1 = createData(s1, 523, 3, A);

Du übergibst s1 gleichzeitig während du es erzeugst ? Das macht doch 
keinen Sinn, oder ?

von mh (Gast)


Lesenswert?

Überleg dir mal genau was der Typ von vals ist.

von Test (Gast)


Lesenswert?

Thomas W. schrieb:
> Du übergibst s1 gleichzeitig während du es erzeugst ? Das macht doch
> keinen Sinn, oder ?

Ich initialisiere die Variable, allokiere Speicherplatz in dieser 
Funktion und gebe einen Zeiger darauf zurück. Spricht für mich nichts 
dagegen. Die ganze Struktur habe ich mir übrigens nicht ausgedacht, 
sondern von hier adaptiert (nur eben mit float anstatt strings) 
https://www.geeksforgeeks.org/flexible-array-members-structure-c/

von Test (oder auch Peter) (Gast)


Lesenswert?

mh schrieb:
> Überleg dir mal genau was der Typ von vals ist.

Oh Mann -- tausend dank ;)
Muss natürlich float und nicht char heißen -> es funktioniert wie 
gewünscht.

Danke

Peter

von Holger (Gast)


Lesenswert?

Hi Peter!

Schau Dir nochmal die die Übergabeparameter dieser Methode an - 
unabhängig vom Typproblem, dass ja bereits gelöst ist :)
1
struct data *createData(struct data *s, int id, int a_size, float a[]) { 
2
3
    s = malloc( sizeof(*s) + sizeof(float) * a_size); 
4
...
5
    return s; 
6
7
}

Den Pointer auf "struct data" zu übergeben ist hier ohne Wirkung.

Auf folgende Art hast Du wesentlich sinnvolleren Code und man überlegt 
nicht erst, was Du machen wolltest ;)
1
struct data *createData(int id, int a_size, float a[]) { 
2
    struct data *s, 
3
    s = malloc( sizeof(*s) + sizeof(float) * a_size); 
4
...
5
    return s;
6
} 
7
...
8
int main(void) {
9
  float A[] = {1.0, 7.5, 9.3};
10
  struct data *s1 = createData(523, 3, A);
11
...
12
  return 0;
13
}

Du hast praktisch einen Übergabeparameter als Stackvariable missbraucht 
;) sollte man nicht tun.

Gruß Holger

von Dirk B. (dirkb2)


Lesenswert?

Peter L schrieb:
> Das float-Array wird
welches float-Array?

Test schrieb:
> Ich initialisiere die Variable, allokiere Speicherplatz in dieser
> Funktion und gebe einen Zeiger darauf zurück. Spricht für mich nichts
> dagegen.

Warum dann aber als Parameter der Funktion und nicht lokal in der 
Funktion?

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.