Merkwürdiges Ergebnis beim Aneinanderhängen von Arrays

#1

Guten Tag,

gleich vorneweg, ich bin kein C/C++ Entwickler, will aber um die Sprache besser kennenzulernen ein älteres Projekt nochmal in der Sprache entwickeln :wink:

Ich habe folgende Structs:

	double x;
	double y;
};

struct PointContainer {
	int size;
	Point* points;
};```

Und folgende Operation zum "Addieren" zweier PointContainer:

```PointContainer add(PointContainer container1, PointContainer container2) {
	PointContainer result = {};
	result.size = container1.size + container2.size;
	Point* points = new Point[result.size];
	points = container1.points;
	Point* temp = points + (sizeof(Point) * container1.size);
	temp = container2.points;
	result.points = points;
	return result;
}```

Zum Test nutze ich zwei Container, die denselben Inhalt haben, folgende 12 Punkte:


[2.000000, 2.000000]
[3.000000, 4.000000]
[5.000000, 2.000000]
[9.000000, 3.000000]
[10.000000, 5.000000]
[11.000000, 4.000000]
[12.000000, 3.000000]
[12.000000, 6.000000]
[4.000000, 8.000000]
[6.000000, 8.000000]
[4.000000, 10.000000]
[7.000000, 10.000000]



Wenn ich nun zwei Container mit je diesen 12 Punkten "addiere", erhalte ich folgendes Bild:

[2.000000, 2.000000]
[3.000000, 4.000000]
[5.000000, 2.000000]
[9.000000, 3.000000]
[10.000000, 5.000000]
[11.000000, 4.000000]
[12.000000, 3.000000]
[12.000000, 6.000000]
[4.000000, 8.000000]
[6.000000, 8.000000]
[4.000000, 10.000000]
[7.000000, 10.000000]
[0.000000, 2.000000]
[2.000000, 3.000000]
[4.000000, 5.000000]
[2.000000, 9.000000]
[3.000000, 10.000000]
[5.000000, 11.000000]
[4.000000, 12.000000]
[3.000000, 12.000000]
[6.000000, 4.000000]
[8.000000, 6.000000]
[8.000000, 4.000000]
[10.000000, 7.000000]



Wie man sieht, ist die erste Liste komplett drin, bei der zweiten "schleicht" sich am Anfang eine 0 ein und alle anderen Werte sind dementsprechend verrutscht.
In der Funktion setze ich (nach meinem laienhaften Verständnis) eigentlich den Pointer korrekt auf das Ende des ersten Containers um: Größe des Structs Point * Menge an Elementen

Habe ich da irgendwo einen groben Schnitzer drin?

Grüße,
Shadoka
#2

Ich bin kein C+±Könner, daher ist meine Antwort mit Vorsicht zu genießen.
Meiner Meinung nach erzeugst du mit Zeile 4 nur ein Memory-Leak und nutzt den angeforderten Speicher nicht, weil du den Pointer points direkt in Zeile 5 wieder überschreibst. Du müsstest in Zeile 5 den Inhalt von container1.points in das neu erzeugte Array kopieren.
Die Berechnung der neuen Zieladresse sollte eigentlich passen, allerdings überschreibst du den Wert in Zeile 7 gleich wieder, statt den Inhalt von container2.points dorthin zu kopieren.

#3

Ein bisschen googlen hat mir in Bezug auf deine Antwort die “memcpy”-Funktion geliefert.
Folgende Änderung habe ich eingebaut, was leider die Situation verschlimmert hat :smiley:

	PointContainer result = {};
	result.size = container1.size + container2.size;
	Point* points = new Point[result.size];
	memcpy(points, container1.points, sizeof(Point) * container1.size);
	Point* temp = points + (sizeof(Point) * container1.size);
	memcpy(temp, container2.points, sizeof(Point) * container2.size);
	result.points = points;
	return result;
}```

Resultat:

[2.000000, 2.000000]
[3.000000, 4.000000]
[5.000000, 2.000000]
[9.000000, 3.000000]
[10.000000, 5.000000]
[11.000000, 4.000000]
[12.000000, 3.000000]
[12.000000, 6.000000]
[4.000000, 8.000000]
[6.000000, 8.000000]
[4.000000, 10.000000]
[7.000000, 10.000000]
[1685979687890133000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000.000000, 1014934869664
21090000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000.000000]
[1320131340831916700000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000.000000, 1348147292795322000000.000000]
[1361751537953883400000000000000000000000000000000000000000000000000000.000000,
21222403066746053000000000000000000000000000000000000000000000000000000000000000
000000000.000000]
[0.000000, 3841672.642741]
[436433992385798600000000000000000000000000000000000000000000000000000.000000, 2
12113490300415130000000000000000000000000000000000000000000000000000000000000000
00000000.000000]
[6227641760882200100000000000000000000000000000000000000000000000000000000000000
0000000000.000000, 3238278141480323000000000000000000000000000000000000000000000
0000000000000000000000000000.000000]
[0.000000, 283261872709003320000000000000000000000000000000000000000000000000000
000000000000000000000000000000000.000000]
[0.000000, 0.000000]
[4963095822651991100000000000000.000000, 158056482267047140000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000.000000]
[0.000000, 113835526446223920000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000.000000]
[3391939914609950300000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000.000000, 276980234011883630000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000.000000]
[1730313488136362000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000.000000, 21667328005746248000000000000000000000000000
0000000000000000.000000]



Ich entschuldige mich bei allen Profis, denen vielleicht bei meiner Nutzung von memcpy schlecht geworden ist :D
#4

Ich bin mir jetzt nicht ganz sicher, wie sich C++ verhält, aber bei Delphi war es so, dass man bei Pointerarithmetik mit typisierten Pointern nicht byteweise, sondern “strukturgrößenweise” rechnet.
Dadurch wird aus Zeile 6 dann: Point* temp = points + container1.size;

#5

Jawoll, wieder einmal hat sich der Spruch bewahrheitet “Das Problem sitzt vor dem Bildschirm” :smiley:
Danke!

#6

Bevor Du an C++ verzweifelst: Du bit nicht allein! Die Sprache hat einige Designg-Schwächen, die man kennen sollte:
C++ Frequently Questioned Answers

bye
TT

#7

An der Seite bin ich auch schon vorbeigestolpert @Timothy_Truckle :smiley:

Und ich beschäftige mich ja freiwillig mit der Sprache, von daher halte ich mich sowieso mit meiner Meinung dazu zurück :wink:
Die Welt hat schon genug Meinungen zu dem Thema gehört, da braucht sie nicht noch meine…