Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Funkcja źle zwraca tablicę znaków

Ostatnio zmodyfikowano 2017-09-08 00:34
Autor Wiadomość
adi1525
Temat założony przez niniejszego użytkownika
Funkcja źle zwraca tablicę znaków
» 2017-09-07 23:50:08
Witam, na potrzeby programu na mikroprocesorze potrzebuję funkcję, która będzie odczytywać tekst po bajcie a następnie zwróci je jako tablica.
Mam problem z programem ponieważ nie ważne jakie znaki wpiszę, funkcja printf wypisuję mi "(". Ktoś pomoże ?

C/C++
uint8_t EUSART1_Read( void )
{
    return getchar();
}
uint8_t * EUSART1_ReadString( void )
{
    int i = 0;
    uint8_t word[ 10 ];
    while( 1 )
    {
        word[ i ] = EUSART1_Read();
        if( word[ i ] == '\n' )
             break;
       
        i++;
    }
    word[ i ] = NULL;
    return word;
}
int main( void )
{
    printf( "%s", EUSART1_ReadString() );
   
    return 0;
}
P-164714
karambaHZP
» 2017-09-07 23:58:58
Nie można zwracać lokalnie utworzonej tablicy bo ma zasięg tylko tej jednej funkcji.
Po wyjściu z funkcji tablica traci ważność, a wskaźnik zwrócony z funkcji wskazuje na nieważny obszar w pamięci.
Potrzebujesz tablicy z dynamicznie alokowaną pamięcią.

C/C++
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


uint8_t EUSART1_Read( void )
{
    return getchar();
}
uint8_t * EUSART1_ReadString( void )
{
    int i = 0;
    uint8_t * word =( uint8_t * ) malloc( 10 );
    while( 1 )
    {
        word[ i ] = EUSART1_Read();
        if( word[ i ] == '\n' )
             break;
       
        i++;
    }
    word[ i ] = NULL;
    return word;
}
int main( void )
{
    uint8_t * word = EUSART1_ReadString();
    printf( "%s", word );
    free( word );
   
    return 0;
}

edit: dopisałem zwalnianie pamięci, bo zapomniałem.
Czy jest gwarancja, że pobranych znaków nie będzie więcej niż miejsc w buforze.
P-164715
adi1525
Temat założony przez niniejszego użytkownika
» 2017-09-08 00:13:11
Dzięki, też to przetestowałem i działa, a mógłbyś mi jeszcze powiedzieć czemu w takim razie wywołanie elementu tablicy:

C/C++
int main( void )
{
    printf( "%c", EUSART1_ReadString()[ 2 ] );
   
    return 0;
}
zwraca mi poprawną wartość ?

10 to wartość przykładowa, później będę ją kontrolował.
P-164716
karambaHZP
» 2017-09-08 00:20:38
Funkcja zwraca wskaźnik na początek tablicy, a zapis
EUSART1_ReadString()[ 2 ]
 wyłuskanie wartości trzeciego elementu tej tablicy.
Należy zadbać aby nie było możliwości odwoływać się do elementów poza tablicą.

10 to wartość przykładowa, później będę ją kontrolował.
OK.
P-164717
adi1525
Temat założony przez niniejszego użytkownika
» 2017-09-08 00:24:47
Jest jeszcze jeden mały problem ;) ponieważ kompilator XC8 nie wspiera dynamicznego alokowania pamięci. Czy mógłbyś mnie nakierować jak to zrobić inaczej, może być ogólnie.

Na mikroprocesorze bez dynamicznej alokacji mi to działa. Nie wiem czy to jest bezpieczne tak to zostawić.
P-164718
karambaHZP
» 2017-09-08 00:31:18
Może lepiej przekazuj tablicę do funkcji z main().
C/C++
#include <stdio.h>
#include <stdint.h>


uint8_t EUSART1_Read( void )
{
    return getchar();
}
void EUSART1_ReadString( uint8_t * word, int size )
{
    int i = 0;
    while( i <( size - 1 ) )
    {
        word[ i ] = EUSART1_Read();
        if( word[ i ] == '\n' )
             break;
       
        i++;
    }
    word[ i ] = NULL;
}
int main( void )
{
    uint8_t word[ 10 ];
    EUSART1_ReadString( word, 10 );
    printf( "%c", word[ 2 ] );
   
    return 0;
}

C dopuszcza VLA, ale zwracanie lokalnej tablicy przez wskaźnik i odwoływanie się do tej pamięci jest UB.
P-164719
adi1525
Temat założony przez niniejszego użytkownika
» 2017-09-08 00:34:58
Dobrze, dzięki wielkie za informacje bardzo mi pomogłeś ;)
P-164720
« 1 »
  Strona 1 z 1