Я хочу сделать функцию strncpy напрямую, вы можете просмотреть мой код? Ошибка шины - PullRequest
0 голосов
/ 02 февраля 2020

Я хочу сделать strncpy функцией по коду, а не с помощью библиотеки или заголовка

, но есть ошибка шины zsh ..... Что не так с моим кодом? Что такое ошибка шины zsh ??

#include <stdio.h>
#include <string.h>

char    *ft_strncpy(char *dest, char *src, unsigned int n)
{
    unsigned int    i;

    i = 0;
    while (i < n && src[i])
    {
        dest[i] = src[i];
        i++;
    }
    while (i < n)
    {
        dest[i] = '\0';
        i++;
    }
    return (dest);
}

int main()
{
    char         *A = "This is a destination sentence";
    char         *B = "abcd";
    unsigned int  n = 3;

    printf("%s", ft_strncpy(A, B, n));
}

Ответы [ 2 ]

3 голосов
/ 02 февраля 2020

Ваша реализация strncpy в порядке, сверхъестественная семантика подверженной ошибкам функции реализована правильно (за исключением типа n, который должен быть size_t).

Ваша тестовая функция неверно: вы передаете адрес строковой константы как целевой массив, вызывая неопределенное поведение, когда ft_strncpy() пытается записать в него. Строковая константа не должна быть записана в. Компилятор может поместить их в постоянную память, если она доступна. В вашей системе запись в постоянную память вызывает ошибку шины, как сообщает оболочка.

Вот модифицированная версия с локальным массивом в качестве места назначения:

int main()
{
    char          A[] = "This is a destination sentence";
    const char   *B = "abcd";
    unsigned int  n = 3;

    printf("%s\n", ft_strncpy(A, B, n));
    return 0;
}
3 голосов
/ 02 февраля 2020

Ваш код демонстрирует одно из очень тонких различий в C между массивом и указателем. Строка:

char *A = "This is a destination sentence";

объявляет A как указатель на символ (строку), а затем инициализирует этот указатель на адрес строкового литерала . Этот строковый литерал имеет значение константа , и компилятору разрешено размещать его в области памяти, доступной только для чтения . Затем, когда вы передаете эту память функции ft_strncpy ( через ее адрес), вы пытаетесь изменить эту постоянную память.

Если вместо этого вы используете следующее :

char A[] = "This is a destination sentence";

затем вы объявляете A как массив символов и инициализируете этот массив данными из строкового литерала. Таким образом, компилятор теперь знает, что массив является модифицируемым (вы не включили квалификатор const), и поместит этот массив в память, которую можно прочитать из записанных и к.

...