GCC ARM 2016q1, Ergebnis von Deklarationsreihenfolge abhängig

OP #4625556
Grüß euch

Ich benötige für eine Kurvenglättung eine Interpolationsmethode und habe 
aus diesem Grund eine kurze Funktion geschrieben, die kubische Splines 
erzeugt.

Die Ergebnisse der Funktion bestehen aus den drei Koeffizienten der 
Splines und werden in eine Struktur gepackt.
1
struct Spline
2
{
3
  float a3;
4
  float a2;
5
  float a1;
6
};


Nun habe ich folgendes Problem. Aus irgendeinem Grund hängt das 
Rechenergebnis der Interpolation von der Reihenfolge ab mit der ich die 
Variablen vor dem Funktionsaufruf anlege.

Und zwar rechnen folgende Zeilen richtig:
1
int32_t start;
2
int32_t high;
3
int32_t mid;
4
Spline spline_cubic[3] = {};
5
float x[4] = {0.1, 1.3, 1.9, 2.1};
6
float y[4] = {1.3, 1.5, 1.7, 2.1};
7
uint32_t n = 4;
8

9
splineCubicSet(x, y, n, spline_cubic);

Und folgende Zeilen falsch?
1
int32_t start;
2
int32_t high;
3
int32_t mid;
4
float x[4] = {0.1, 1.3, 1.9, 2.1};
5
float y[4] = {1.3, 1.5, 1.7, 2.1};
6
uint32_t n = 4;
7
Spline spline_cubic[3] = {};
8

9
splineCubicSet(x, y, n, spline_cubic);


Hat jemand ev. eine Idee woran das liegen könnte?
Gast #4625602
Moin,

Initialisiere deine Deklarationen mal vernünftig.

Sieht mir danach aus, als wenn du nicht initialisierte Variablen 
benutzt. Das würde auch dein Fehlerbild erklären.
OP #4625643
Jim M. schrieb:
> Außer Stack Overflow würde mir da ertmal nix zu einfallen.
> Zeige mal den vollständigen Code, da ist zu 99.99% was anderes faul.


Achtung die Funktion nutzt "variable length" arrays. Ich mach mich grad 
ran nochmal die leider recht komplexen Indizes zu prüfen...

Uninitialisierte Variablen seh ich keine.

1
__STATIC_INLINE void splineCubicSet(float x[], float y[], uint32_t n, Spline spline[])
2
{
3
  float h[n-1] = {};
4
  float u[n-2] = {};
5
  float z[n-2] = {};
6

7
  float tmp[2];
8
  uint32_t i;
9

10
  /* Do the fist one "by hand */
11
  h[0] = x[1] - x[0];
12
  h[1] = x[2] - x[1];
13
  tmp[0] = 2 * (x[2] - x[0]);
14
  u[0] = h[1] / tmp[0];
15
  tmp[1] = (3 / h[1]) * (y[2] - y[1]) - (3 / h[0]) * (y[1] - y[0]);
16
  z[0] = tmp[1] / tmp[0];
17

18
  /* Iterate others */
19
  for (i = 2; i < (n - 1); i++)
20
  {
21
    h[i] = x[i + 1] - x[i];
22
    tmp[0] = (2 * (x[i + 1] - x[i - 1])) - h[i - 1] * u[i - 2];
23
    u[i - 1] = h[i] / tmp[0];
24
    tmp[1] = (3 / h[i]) * (y[i + 1] - y[i])
25
        - (3 / h[i - 1]) * (y[i] - y[i - 1]);
26
    z[i - 1] = (tmp[1] - h[i - 1] * z[i - 2]) / tmp[0];
27
  }
28

29
  /* Do the last one "by hand */
30
  spline[n - 2].a2 = z[n - 3];
31
  spline[n - 2].a1 = (y[n - 1] - y[n - 2]) / h[n - 2]
32
      - (h[n - 2] * 2 * spline[n - 2].a2) / 3;
33
  spline[n - 2].a3 = -spline[n - 2].a2 / (3 * h[n - 2]);
34

35
  /* Iterate others */
36
  for (i = n - 2; i >= 1; i--)
37
  {
38
    spline[i].a2 = z[i - 1] - u[i - 1] * spline[i + 1].a2;
39
    spline[i].a1 = (y[i + 1] - y[i]) / h[i]
40
        - (h[i] * (spline[i + 1].a2 + 2 * spline[i].a2)) / 3;
41
    spline[i].a3 = (spline[i + 1].a2 - spline[i].a2) / (3 * h[i]);
42
  }
43

44
  /* Do the fist one "by hand */
45
  spline[0].a2 = 0;
46
  spline[0].a1 = (y[1] - y[0]) / h[0]
47
      - (h[0] * (spline[1].a2 + 2 * spline[0].a2)) / 3;
48
  spline[0].a3 = (spline[1].a2 - spline[0].a2) / (3 * h[0]);
49
}
Gast #4625672
1
  /* Iterate others */
2
  for (i = n - 2; i >= 1; i--)
3
  {
4
    spline[i].a2 = z[i - 1] - u[i - 1] * spline[i + 1].a2;

Wenn i=n-2 ist, ist für n=4 also i=2. Somit ist i+1=3, und spline[i+1] 
ist ein Buffer Overflow, da spline nur 3 Elemente groß ist.

Und wieder einmal ist der Programmierer, und nicht der Compiler, schuld 
:P
OP #4625691
Dr. Sommer schrieb:
>
1
>   /* Iterate others */
2
>   for (i = n - 2; i >= 1; i--)
3
>   {
4
>     spline[i].a2 = z[i - 1] - u[i - 1] * spline[i + 1].a2;
5
>
>
> Wenn i=n-2 ist, ist für n=4 also i=2. Somit ist i+1=3, und spline[i+1]
> ist ein Buffer Overflow, da spline nur 3 Elemente groß ist.
>
> Und wieder einmal ist der Programmierer, und nicht der Compiler, schuld
> :P


Ah Gott sei Dank!!!
Ja dass der Programmierer Schuld ist war eh klar :)

Ich hab den Algorithmus zuerst in MATLAB runtergeschrieben, dass ja bei 
Indizes 1 zu zählen beginnt. Und als ob das nicht mühsam genug wär 
kommen einige temporäre Variablen dann halt auch noch entweder N-1 oder 
N-2 mal vor... was die Sache mit den Indizes nicht unbedingt 
vereinfacht. :)

Danke!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.