Как заполнить символьный указатель внутри другого указателя без использования динамического выделения памяти - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь назначить символьный указатель внутри другого указателя в структуре.В моей среде нет malloc / calloc, поэтому динамическое выделение памяти не вариант.Как я могу сделать возможным заполнение указателя на символ в функции read_string_from_byte_array ()?

    typedef struct custom_string
    {
        char textt[5];
        int length;
    }custom_string;

    typedef struct custom_string_container
    {
        custom_string* string;
    }custom_string_container;

    void read_string_from_byte_array(custom_string_container* string_container)
    {
        char* byte_array = "12345";
        int i;

        puts("assigning");
        for(i = 0; i < 5; i++)
        {
            string_container->string->textt[i] = byte_array[i]; //failing with exit code 139
        }

        puts("done assigning");

    }



    void main()
    {
        //dynamic memory allocation is strictly prohibited
        custom_string_container string_container;

        read_string_from_byte_array(&string_container);
        printf("read string is %s \n", string_container.string->textt);

    }

1 Ответ

0 голосов
/ 30 января 2019

, если вы не хотите динамического выделения в куче, замените

typedef struct custom_string_container
{
    custom_string * string;
}custom_string_container;

на

typedef struct custom_string_container
{
    custom_string string;
}custom_string_container;

и, конечно, при необходимости замените '->' на '.'

также предупреждает с помощью

    for(i = 0; i < 5; i++)
    {
        string_container->string->textt[i] = byte_array[i]; //failing with exit code 139
    }

отсутствует нулевой завершающий символ, это проблема при выполнении

printf("read string is %s \n", string_container.string->textt);

, если вы хотите сохранить 5 символов (без учета нулевого символа)) добавьте string_container->string->textt[i] = 0; после для или замените i < 5 на i <= 5, чтобы также скопировать нулевой символ

и, конечно, замените char textt[5]; на char textt[6]; в struct custom_string

Обратите внимание, что писать 6 в размере, тогда как 5 или 6 в другом месте опасно, если вы измените размер, гораздо безопаснее использовать sizeof

Окончательно со всемиизменения:

typedef struct custom_string
{
    char textt[6];
    int length;
}custom_string;

typedef struct custom_string_container
{
    custom_string string;
}custom_string_container;

void read_string_from_byte_array(custom_string_container* string_container)
{
    char* byte_array = "12345";
    int i;

    puts("assigning");
    for(i = 0; i < sizeof(string_container->string.textt); i++)
    {
        string_container->string.textt[i] = byte_array[i]; 
    }
    string_container->string.textt[i] = 0;

    puts("done assigning");

}



void main()
{
    //dynamic memory allocation is strictly prohibited
    custom_string_container string_container;

    read_string_from_byte_array(&string_container);
    printf("read string is %s \n", string_container.string.textt);

}

Исполнение:

assigning
done assigning
read string is 12345 

и valgrind :

pi@raspberrypi:~ $ valgrind ./a.out 
==8507== Memcheck, a memory error detector
==8507== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8507== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8507== Command: ./a.out
==8507== 
assigning
done assigning
read string is 12345 
==8507== 
==8507== HEAP SUMMARY:
==8507==     in use at exit: 0 bytes in 0 blocks
==8507==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==8507== 
==8507== All heap blocks were freed -- no leaks are possible
==8507== 
==8507== For counts of detected and suppressed errors, rerun with: -v
==8507== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

Обратите внимание, что копия вread_string_from_byte_array можно просто сделать, используя strncpy (не strcpy в случае, если byte_array слишком долго для запоминания в textt ), а не для петля

...