Inkonsistente Daten am Zeiger

Hallo zusammen,
ich habe ein seltsames Verhalten in dieser Klasse.
Daten die sie am ende des Zeiger befinden verhalten sich inkonsistent. Bitte Beachtet die Variable "manuallyData"

/// <summary>
/// Variable to save Pointer for push in manually loop
/// </summary>
byte* manuallyData;

/// <summary>
/// This method is for routing data if the systemmode manualy 
/// </summary>
/// <param name="data"></param>
/// <param name="dataSize"></param>
void DataRouter::routeManuallyData(byte* data, int dataSize) {
	
	if (data[0] == ABLE_TO_QUEUE) {
		Rec newData;
		int dataCount = dataSize / sizeof(byte);
		memcpy(newData.data, data + 1, (dataCount - 1) * sizeof(byte));
		dataManuallyQueue.push(&newData);
	}
	else if(data[0] == 0) {
		Serial.println("point1");
		for (size_t i = 0; i <= 14; i++)
		{
			if(i == 14){
				Serial.println(" " + String(data[i]));
			}
			else {
				Serial.print(" " + String(data[i]));
			}
		}
		
		manuallyData = data;
		Serial.println("point2");
		for (size_t i = 0; i <= 14; i++)
		{
			if (i == 14) {
				Serial.println(" " + String(manuallyData[i]));
			}
			else {
				Serial.print(" " + String(manuallyData[i]));
			}
		}
	
		manuallyDataIsPushing = true;
	}
}

/// <summary>
/// This methode is for pushing data direct to loop,
/// if systemmode is on manuealy and the data is need to process direct
/// </summary>
/// <param name="data"></param>
/// <returns>A byte pointer</returns>
byte* DataRouter::pushManualLyDataToLoop(){
	manuallyDataIsPushing = false;
	Serial.println("point3");
	for (size_t i = 0; i <= 14; i++)
	{
		if (i == 14) {
			Serial.println(" " + String(manuallyData[i]));
		}
		else {
			Serial.print(" " + String(manuallyData[i]));
		}
	}
	return manuallyData;
}

Output:
point1
0 4 2 3 4 5 6 7 8 9 10 11 12 13 14
point2
0 4 2 3 4 5 6 7 8 9 10 11 12 13 14
point3
0 0 3 0 0 0 0 7 8 9 10 11 12 13 14

Leider fehlen etliche Details zu Deinem Code.

Diese Daten liegen vermutlich im Stack, können jederzeit überschrieben werden.

Entschuldigung. die Codeführung läuft in diesem Fall immer in's "else if", das erste "If" setzt den Datensatz in die Queue, das "Else if" gibt den Datensatzzeiger durch an die Variable und setzt das Flag.

Dann zeige doch mal das Testprogramm, das die Ausgabe erzeugt.

Die Klasse bildet eine mittle Schicht von 4, den ganzen Code zu zeigen wäre glaube ich etwas viel. Der Output wird, wie oben im Code dargestellt am Ende, direkt in dieser Klasse generiert. D.h. die unterste Schicht bildet in diesem Fall der Datenempfang via I2C Pullup, der Zeiger auf die Daten wird durch den Comswitch ( der instantisiert mir die verschiedenen Kommunikationstechniken => empfang über Bluetooth, Serial oder I2C...) durch gereicht in den Datenrouter ( Klasse mit dem geposteten Codeausschnitt), dort setze ich das Flag und lass im loop dann die Daten abholen.
=> loop

	//This process is working on systemstate "MANUALLY"
	if (_mainDataRouter.currentSystemState == MANUALLY) { processOnManuely(); }
void processOnManually() {
	//Get data from com and process it direct
	if (_mainDataRouter.manuallyDataIsPushing==true) {
		byte* returnedData = _mainDataRouter.pushManualLyDataToLoop();
		
		switch (returnedData[1])
		{
		case 1:
			break;
		case 4:
			_mainDataRouter.currentSystemState = AUTOMATIC;
			Serial.println(F("Automatic"));
		default:
			break;
		}
	}
	else if (!_mainDataRouter.dataManuallyQueue.isEmpty()) {
		//pop data from queue
		ImputDataSet newData;
		_mainDataRouter.dataManuallyQueue.pop(&newData);

		switch (newData.data[0]) {
		case 2:
			
			break;
		case 3:
			
			break;
		default:
			break;
		}
	}
}

Ich hoffe das ist einigermaßen ausreichend erklärt.

Ich verstehe dich nicht.
Das ist ein Problem.

Dein Code ist untestbar!
Das zweite Problem.

Warum hampelst du in C++ so intensiv mit Zeigern rum?
Das war unter C schon gefährlich, unter C++ ist es meist unnötig.

  1. Wo kommen die magischen 14 her?
  2. Wozu das unsinnige If Konstrukt?
  3. Warum die aufwendige Konvertierung zu String?
1 Like

Zeig doch einen minimalen "ganzen Code", der nichts macht außer den Fehler zu zeigen.
Falls das dann überhaupt noch nötig ist.

Wie kann man eine Klasse definieren ohne Testcode dafür ?

Das "IF -> Serial.print()" ist doch nur um zu zeigen, was Tatsache in den Arrays ist, zum debuggen und euch mein Problem darzustellen, da ja bei der Übergabe des Zeiger auf die Daten alles korrekt ist, aber wenn ich sie abholen möchte, fehlt die Hälfte . Ich gebe den Zeiger lediglich weiter von data nach _manuallyData. Die magische 14 ist die mir bewusste Größe des Array, das ich rein gebe( nach Protokoll). Ich würde auch lieber die Daten durchreichen, aber der Arduino ist einfach stark eingegrenzt mit Speicher, deswegen die Zeiger.

Der Fehler ist unten in meinem Post dargestellt. Ich übergebe an die Methode:

DataRouter::routeManuallyData(byte* data, int dataSize){}

einen Zeiger auf die Daten >

0 4 2 3 4 5 6 7 8 9 10 11 12 13 14

an _manuallyData weiter

und ohne dass Manipulation oder Überschreibung an den Daten am Zeiger vorgenommen wurde bekomme ich beim Abruf der Daten mit der Methode:

byte* DataRouter::pushManualLyDataToLoop(){}

das zurück:

0 0 3 0 0 0 0 7 8 9 10 11 12 13 14

for (size_t i = 0; i <= 14; i++) 
{   Serial.write(' '); Serial.print( manuallyData[i] ); } 
Serial.println();

Weil das zu einfach wäre.

Vermutlich zeigt der Zeiger auf temporäre Daten auf dem Stack, wie @DrDiettrich bereits vermutet, aber das kann man nicht sehen.
Schnipsel ohne Variablendefinition ist kein Programmcode.

Es fehlt aber alles, das für die unterschiedliche Ausgabe zwischen point2 und point3 schuld sein könnte.

Sind denn die Original-Daten überschrieben, oder eine Kopie davon?

An der Stelle irrst du dich!
Es kann sein, dass du die Manipulation nicht siehst....
Aber stattfinden, das wird sie wohl.

Es gibt Möglichkeiten, Arrays abzuhandeln, ohne Zeiger und auch ohne die Array[Syntax] zu verwenden. Damit auch ohne magische Zahlen.

Wenn irgend möglich, dann setze darauf!
Das schafft dir viele Probleme vom Hals.

Hier mal ein Beispiel aus meiner Wühlkiste:

#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"



template<typename T, size_t N> void printArray(Print &p, T (&array)[N])
{
   p << F("---- printArray start------ ")  << endl
     << F("Das Array hat ") << N << F(" Zellen") << endl
     << F("Zellen groesse: ") << sizeof(T) << F(" Byte") << endl;
   for(T &zelle:array) p << ' ' << zelle;
   p  << endl 
      << F("--- printArray ende ------- ")  << endl  << endl;
}

struct Rechteck: Printable
{
  float x;
  float y;
  
  Rechteck(float x,float y):x{x},y{y}{}

  virtual size_t printTo(Print &p) const
  {
    size_t len{0};
    len += p.print('(');
    len += p.print("x: ") + p.print(x) + p.print(' ');
    len += p.print("y: ") + p.print(y) + p.print(' ');
    len += p.print("flaeche: ") + p.print(x*y);
    len += p.print(')');
    return len;
  }
};


byte  testa[] {1,3,5,7,89,};
int   testb[] {-34,77,42,-4711};
float testc[] {PI,2.666,17.0/43.0};
Rechteck testd[] {{2.2,3.55},{2.1,4.8},{5.5,7.5}};

void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;
  
  printArray(Serial, testa);
  printArray(Serial, testb);
  printArray(Serial, testc);
  printArray(Serial, testd);
}

void loop() 
{

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.