Variable wird überschrieben

hhunderter

Erfahrenes Mitglied
Hi, ich versuche gerade ein Script aup die Beine zu stellen, womit ich Daten von einem COM-Port schreiben und lesen kann.
Alles hatt wunderbar funktionier, jetzt wollte ich den Code einkürzen und eine Funktion hinzufügen.
Mein problem ist jetzt, dass meine Variablen nicht richtig gesetzt werden (kommt immer nur der letzte Wert).

Hier mein code:
C++:
/**************************************************

file: demo_tx.c
purpose: simple demo that transmits characters to
the serial port and print them on the screen,
exit the program by pressing Ctrl-C

compile with the command: gcc demo_tx.c rs232.c -Wall -Wextra -o2 -o test_tx

**************************************************/

#include <stdlib.h>
#include <stdio.h>

#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

#include "rs232.h"

char* get_data();

int cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
bdrate=19200;       /* 19200 baud */
char mode[]={'8','N','1',0};

char quiet = 0;


int main()
{
   
    if(RS232_OpenComport(cport_nr, bdrate, mode))
    {
        printf("Can not open comport\n");
       
        return(0);
    }
   
    #ifdef _WIN32
        Sleep(1000);
    #else
        usleep(1000000);  /* sleep for 1 Second */
    #endif
   
    get_data("/ACCESS:0\n",0);
    char* distance = get_data("/DISTANCE1\n",1);
    char* echoraw = get_data("/ECHORAW1\n",1);
   
    printf("received : %s\n", " ");
    printf("distance : %s\n", distance);
    printf("received : %s\n", " ");
    printf("echoraw : %s\n", echoraw);

    return(0);
}

char* get_data(char str[],int print)
{
    int i=0, n;
    unsigned char buf[4096];
    char* rett = "";
   
    n = 0; memset(buf, 0, sizeof(buf));
    n = RS232_PollComport(cport_nr, buf, 4095);
   
    RS232_cputs(cport_nr, str);
    if( !quiet ) printf("sent: %s", str);

    #ifdef _WIN32
        Sleep(1000);
    #else
        usleep(1000000);  /* sleep for 1 Second */
    #endif
   
    n = 0; memset(buf, 0, sizeof(buf));
    n = RS232_PollComport(cport_nr, buf, 4095);
    if( print )
    {
        if(n > 0)
        {
            buf[n] = 0;   /* always put a "null" at the end of a string! */

            for(i=0; i < n; i++)
            {
                if(buf[i] < 32)  /* replace unreadable control-codes by dots */
                {
                    buf[i] = ' ';
                }
            }
        }
        rett = (char *)buf;
        if( !quiet ) printf("received : %s\n", rett);
    }
    else
    {
        n = 0; memset(buf, 0, sizeof(buf));
    }
   
    return rett;
}

Die Funktionen der Seriellenschnittstelle kommt hier her:http://www.teuniz.net/RS-232/index.html
 

cwriter

Erfahrenes Mitglied
Hi

Alles hatt wunderbar funktionier, jetzt wollte ich den Code einkürzen und eine Funktion hinzufügen.
Und genau das ist auch das Problem.
Du erzeugst in get_data() den Stack-Array "buf", liest darin ein, und setzt ganz zum Schluss rett auf die Adresse dieses Stack-Arrays. Nun beendet diese Funktion, setzt also den Stackpointer zurück und buf ist Vogelfrei: Jede Funktion, die ab dann aufgerufen wird (und Stack benötigt, unter x86 also so ziemlich jede), darf deinen buf überschreiben.
Es gibt nun 2 Möglichkeiten:
1) Du machst
C:
char* buf = calloc(4096, 1); //damit kannst du dir das memset auf 0 sparen, ansonsten geht auch malloc
if(buf == NULL) {/*...*/}
//und dann normal weiter, aber am Schluss unbedingt den Buffer wieder freigeben (free()).
Das Problem hierbei: Man muss höllisch aufpassen, dass man das free() nicht vergisst.

Option 2: Statt buf innerhalb von get_data() zu erzeugen, erzeugst du buf im Caller und gibst dann (wie str) einfach einen Pointer darauf. Diese Variante ist meist einfacher.

Gruss
cwriter