Forum: PC-Programmierung dataArray als pointer zurück geben


von Marcel (Gast)


Lesenswert?

Hallo,
ich habe eine Funktion, wo ein unit8* dataBuffer übergeben wird. diesen 
muss ich beschreiben und wieder zurückgeben.

file1.c
1
...
2
uint8* dataBuffer
3
...
4
readData( startIndex, dataBuffer, size );

file2.c
1
uint16 readData( uint32 startIndex, uint8* dataBuffer, uint32 size )
2
{
3
    uint8 data[128] = {0};
4
  for(uint32 byte=startIndex; byte<(startIndex+size); byte++)
5
  {
6
    data[byte] = getByte( byte );
7
  }
8
  /* data enthält hier gültige werte */
9
  dataPtr = data;
10
    return 0;
11
}

in der Funktion readData ist data noch korrekt. Heißt 128 Bytes lang und 
richtige Werte.
zurück nach readData in file1.c sind die Daten aber nicht mehr da. 
Zumindest kann ich diese im Debugger nicht sehen.
dataBuffer enthält zwar eine Adresse (ist also vorhanden), aber der 
inhalt ist 0.

Wie bekomme ich die Daten richtig zurückgegeben?

von STK500-Besitzer (Gast)


Lesenswert?

Marcel schrieb:
> zurück nach readData in file1.c sind die Daten aber nicht mehr da.
> Zumindest kann ich diese im Debugger nicht sehen.
> dataBuffer enthält zwar eine Adresse (ist also vorhanden), aber der
> inhalt ist 0.
>
> Wie bekomme ich die Daten richtig zurückgegeben?

Du brauchst keine Poiner-Definition, sondern ein Array, das vorhanden 
ist.
So müsste das laufen:
1
file1.c
2
3
...
4
uint8 dataBuffer[128};
5
...
6
readData( startIndex, &dataBuffer, size );
7
8
9
file2.c
10
11
uint16 readData( uint32 startIndex, uint8* dataBuffer, uint32 size )
12
{
13
  for(uint32 byte=startIndex; byte<(startIndex+size); byte++)
14
  {
15
    dataBuffer[byte] = getByte( byte );
16
  }
17
  /* data enthält hier gültige werte */
18
    return 0;
19
}

von ? DPA ? (Gast)


Lesenswert?

Überlege mal, bei:
1
int a = 1;
2
int b = a;
3
b = 2;

enthält a nachher immer noch 1, weil das 2 verschiedene Werte sind, und 
der Wert von b einfach überschrieben wird. In deiner Code hast du die 
gleiche Situation, nur halt mit Pointern statt mit Integern:
1
int* a = &(int){1};
2
int* b = a; // b zeigt auf das selbe compound literal, auf das auch a zeigt. Die Zeiger haben den selben Wert
3
*b = 2; // der Wert, auf den a und b zeigen, der in dem compound literal oben, auf 2 gesetzt.
4
b = &(int){3}; // Aber jetzt zeigt b auf dieses andere compound literal. a ist das egal, und zeigt weiterhin auf das Alte. a und b sind unabhängige Werte / Zeiger, und hier wird der Zeiger selbst überschrieben, nicht das, auf was er zeigt.

Ausserdem:
 1) Man könnte direkt in dataBuffer schreiben, wieso legst du überhaupt 
einen separaten womöglich zu kleinen Buffer auf dem Stack an, und was 
soll der Offset dort bringen? Mit nem extra buffer müsste man das 
ausserdem nochmal extra kopieren (z.B. mit memcpy). Ich würde den 
einfach weg lassen.
 2) Das startIndex argument kannst du dir eigentlich sparen. Übergib 
einfach dataBuffer+startIndex, dann zeigt das gleich an den Anfang, von 
wo an rein geschrieben werden soll.

Oder willst du einen neuen Buffer in der Funktion erstellen und zurück 
geben? In dem Fall den nicht auf den stack packen, sondern auf dem heap 
reservieren (malloc / calloc), sonst ist er nach der Funktion futsch. In 
dem fall müsste man halt das Augument auf den Zeiger zeigen lassen, den 
man überschreiben will, so das er auf den neuen Buffer zeigt.

von Marcel (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> uint8 dataBuffer[128};
> ...
> readData( startIndex, &dataBuffer, size );

Das hätte ich auch so verstanden. Das Problem ist, dass ich 
dataBuffer[128] nirgendwo finden kann.
nur die Initialisierung finde ich
1
uint8 * dataBuffer;     // Points to the data to write or to the array where data should be copied to.

von Marcel (Gast)


Lesenswert?

? DPA ? schrieb:
> 2) Das startIndex argument kannst du dir eigentlich sparen. Übergib
> einfach dataBuffer+startIndex, dann zeigt das gleich an den Anfang, von
> wo an rein geschrieben werden soll.
Das Problem ist, dass die Funktionen

readData( startIndex, dataBuffer, size ); (hier nur der Aufruf.)
und
getByte( byte );

schon vorhanden sind und ich nicht verändern darf.

von Marcel (Gast)


Lesenswert?

Jetzt habe ich doch noch etwas gefunden

Bei der Initialisierung wir ein Array wohl zugewiesen
1
dataBuffer = dataArray;
und dataArray ist
1
uint8  dataArray [COMPLETE_SIZE];

Habe meine Funktion dann jetzt umgeschrieben zu
1
uint16 readData( uint32 startIndex, uint8* dataBuffer, uint32 size )
2
{
3
  for(uint32 byte=startIndex; byte<(startIndex+size); byte++)
4
  {
5
    dataBuffer[byte] = getByte( byte );
6
  }
7
    return 0;
8
}

Aber trotzdem kann ich den Array im Debugger (mit qtCreator) nicht 
sehen.
Auch nach dataBuffer = dataArray sehe ich zwar den pointer, aber 
inhaltlich sehe ich nichts. Auch da wo der pointer hinzeigt, stehen 
nicht die Werte, die ich aus getByte bekomme.

von Marcel (Gast)


Lesenswert?

Oh man, zu früh geschrieben.
In dataArray  stehen die Werte jetzt aber alle drinn.

von ? DPA ? (der übliche) (Gast)


Lesenswert?

Füge vielleicht noch ein
1
assert(startIndex+size < COMPLETE_SIZE);
oder einen vergleichbaren check in readData ein.

von Adam P. (adamap)


Lesenswert?

Marcel schrieb:
> uint8* dataBuffer

Marcel schrieb:
> uint16 readData( uint32 startIndex, uint8* dataBuffer, uint32 size )

Ich würde mir deine Namensgebung vllt. nochmal überlegen.
Globale und Funktionsparameter gleich zu bennen, irgendwie verwirrend 
auf den ersten Blick.

Hab es zwar grad mal getestet, aber ich wäre davon ausgegangen, dass es 
auf
"Variable shadowing" hinausläuft.

Test:
1
#define COMPLETE_SIZE  32
2
3
uint8_t dataArray[COMPLETE_SIZE];
4
uint8_t* dataBuffer;
5
6
uint8_t getByte(uint32_t index)
7
{
8
  const uint8_t virtualInput[] = "Hallo";
9
10
  return virtualInput[index % 5];
11
}
12
13
uint16_t readData(uint32_t startIndex, uint8_t* dataBuffer, uint32_t size)
14
{
15
  for (uint32_t byte=startIndex; byte<(startIndex + size); byte++)
16
  {
17
    dataBuffer[byte] = getByte(byte);
18
  }
19
  return 0;
20
}
21
22
int main()
23
{
24
  dataBuffer = dataArray;
25
26
  readData(0, dataBuffer, 32);
27
  
28
  return 0;
29
}

: Bearbeitet durch User
von Marcel (Gast)


Lesenswert?

Ich habe noch einmal eine Nachfrage. So ganz funktioniert das noch nicht
1
uint16 readData( uint32 startIndex, uint8* dataBuffer, uint32 size )
2
{
3
  uint32 byte;
4
  uint8 value;
5
  for(uint32 byte=startIndex; byte<(startIndex+size); byte++)
6
  {
7
    value = getByte( byte );
8
    dataBuffer[byte] = value;
9
  }
10
    return 0;
11
}

COMPLETE_SIZE ist mit 384 definiert.
die FUnktion readData wird drei mal Aufgerufen
Aufruf 1
  startIndex = 0
  dataBuffer -> Speicheradresse von dataArray[0]
  size = 128

dataArray[0] bis dataArray[127] sind mit den richtigen werten befüllt.

Aufruf 2
  startIndex = 128
  dataBuffer -> Speicheradresse von dataArray[128]
  size = 128

im ersten durchlauf der For-Schleife ist byte = 128 und value kommt 129 
heraus. Dies ist auch richtig.
Aber das Ergebnis wird nicht in dataBuffer[128] geschrieben, sondern in 
dataBuffer[256] und ab dann immer weiter (also dataBuffer[257]...).

Wieso ist das so?
byte ist 128
und wieso wird dann dataBuffer[byte] woanders reingeschrieben? Es wird 
ja auch die richtige Speiceradresse übergeben.

von Adam P. (adamap)


Lesenswert?

Marcel schrieb:
> uint32 byte;
>   for(uint32 byte=startIndex; byte<(startIndex+size); byte++)

Was machst du da??? Warum definierst du "byte" zwei mal?

Marcel schrieb:
> uint8 value;

Außerdem ist hier uint8 eher falsch, wenn du auch Werte über 255 haben 
möchtest.

Marcel schrieb:
> value = getByte( byte );

Wie sieht denn die Funktion getByte() aus?

: Bearbeitet durch User
von ? DPA ? (der übliche) (Gast)


Lesenswert?

Na wenn dataBuffer = dataArray+128, dann ist  dataBuffer+128 = 
dataArray+128+128 = dataArray+256. Also entweder ist dataBuffer falsch, 
oder startIndex, oder startIndex ist in readData nicht zu dataBuffer 
hinzuzuaddieren. Da müsste man halt wissen, wie die readData Funktion 
tatsächlich gedacht war. Das ist die Art von Sachen, die im Code im 
Idealfall irgendwo mit einem Kommentar Dokumentiert sein sollte.

von Adam P. (adamap)


Lesenswert?

? DPA ? (der übliche) schrieb:
> Na wenn dataBuffer = dataArray+128, dann ist  dataBuffer+128 =
> dataArray+128+128 = dataArray+256.

Ja dann ist der Aufruf aber evtl. falsch:
1
// Richtig
2
readData(0, dataArray, 128);
3
readData(128, dataArray, 128);
4
5
// Falsch
6
readData(0, &dataArray[0], 128);
7
readData(128, &dataArray[128], 128);

Also ich hab es nun mal so runtergeschrieben, und es tut was es soll:
(Hab mir den zweiten Pointer gesparrt, konnte bis jetzt den Sinn nicht 
erkennen).
1
#define COMPLETE_SIZE    384
2
3
uint8_t dataArray[COMPLETE_SIZE];
4
5
uint8_t getByte(uint32_t index)
6
{
7
  return (index + 1);
8
}
9
10
uint16_t readData(uint32_t index, uint8_t *dst, uint32_t count)
11
{
12
  for (uint32_t i=index; i<(index+count); i++)
13
  {
14
    // JA, getByte liefert bei 256 wieder 0, ist mir bewusst.
15
    // Leider haben wir keine genaueren Infos von Marcel
16
    dst[i] = getByte(i);
17
  }
18
19
  return 0;
20
}
21
22
int main()
23
{
24
  readData(0, dataArray, 128);
25
  readData(128, dataArray, 128);
26
27
  return 0;
28
}

: Bearbeitet durch User
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.