#include <stdio.h>
#include <string.h>
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
unsigned int i;
unsigned int dst_len;
i = 0;
dst_len = strlen(dst);
if (dstsize > 0)
{
while (src[i] != '\0' && i < dstsize - 1)
{
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
return (strlen(src));
}
int main(void)
{
char dst[100] = "HelloWorld!";
char dst2[100] = "HelloWorld!";
const char src[11] = "teststring";
int dstsize = -1;
printf("mine : %zu\n", ft_strlcpy(dst, src, dstsize));
printf("%s\n", dst);
printf("string.h : %zu\n", strlcpy(dst2, src, dstsize));
printf("%s\n", dst2);
return (0);
}
Этот код является моим кодом реализации strlcpy самостоятельно.
но у меня есть один сомнительный вопрос.
когда dstsize является отрицательным числом, моя функция не печатает никаких сообщений об ошибках.
но оригинальная ошибка трассировки strlcpy print (возможно, SIGILL в Linux. Я использую OS X)
Я искал большую часть оригинальной библиотеки bsd c на github, но все они работают так же, как мой код. Я хочу знать разницу. как исходная ошибка печати strlcpy, когда dstsize является отрицательным числом?
Суть этого вопроса заключается в том, «как распечатать ошибку ловушки трассировки, когда dstsize является отрицательным числом, как исходная функция? (Я знаю, что он будет преобразован в максимальное число size_t.)»
dstsize
не может быть отрицательным числом, так как это тип size_t
, который является типом без знака. Когда аргумент равен -1, он будет преобразован в беззнаковое значение, которое является максимальным значением size_t.
ага. Я знаю об этом. когда size_t преобразует -1 в максимальное значение size_t, как узнать об этом и об ошибке ловушки трассировки исходной функции? Я просто хочу, чтобы мой код работал как оригинальная функция.
Примечание: const char src[10] = "teststring";
, вероятно, не то, что вам нужно. Здесь src
не завершается нулем, потому что нет места для завершающего нуля. Вы, вероятно, хотите char src[11] = ...
или лучше char src[] = ...
. В последнем случае компилятор позаботится о том, чтобы зарезервировать нужное количество памяти для вашей строки.
@Jabberwocky извини за это. но суть этого вопроса не в этом..
@jyoung Я знаю, поэтому это «примечание». Это бонус, бери или уходи.
@Jabberwocky src
проблема не в том, чтобы заканчиваться нулем. Первое, что делает strlcpy
, это strlen(src)
видит github.com/apple/darwin-xnu/blob/main/osfmk/arm/strlcpy.c . Я думаю, что это случай того, что UB ведет себя по-разному в двух случаях и не имеет ничего общего с dstsize
.
Если вы замените объявление src
на const char *src = "teststring";
, я думаю, ловушки нет.
@PaulHankin, если src выдает ошибку, первый вывод «mine: 10» не должен быть напечатан.
@jyoung src
не завершается нулем, поэтому все ваши тесты бессмысленны.
@jyoung исходная функция strlcpy
также не работает с отрицательным размером, поскольку size_t
не имеет знака.
@Jabberwocky, пожалуйста, еще раз посмотрите на мой вопрос. Я отредактировал код. но происходит та же ошибка
@jyoung, а какой результат вы ожидаете?
@Jabberwocky нужен сигнал ловушки трассировки, как в оригинальной функции.
@jyoung исходная функция strlcpy не задокументирована для этого. Если src
завершается нулем (как в отредактированной версии вашего кода), ваш код работает нормально без каких-либо сообщений об ошибках. Проверьте это: godbolt.org/z/fjPbE15zj. Кстати: не объявляйте свои строки так: const char src[11] = "teststring";
, это плохая практика и чревато ошибками. Сделайте это: const char src[] = "teststring";
Нет смысла вычислять длину строки в dst
для strlcpy
: dst_len = strlen(dst);
бесполезно и контрпродуктивно.
Вот модифицированная версия:
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
size_t i;
i = 0;
while (i + 1 < dstsize && src[i] != '\0') {
dst[i] = src[i];
i++;
}
if (i < dstsize) {
dst[i] = '\0';
}
while (src[i] != '\0') {
i++;
}
return i;
}
Что касается вашего вопроса:
how to print trace trap error when
dstsize
is a negative number?(I know it will be converted tosize_t
max number.)
Если размер адресата, переданный вызывающей стороной, является отрицательным числом, то есть результатом некоторого вычисления, которое производит или могло бы произвести отрицательное число с использованием арифметики со знаком, оно преобразуется в size_t
по модулю SIZE_MAX + 1
, следовательно, значение огромно.
Вы можете обнаружить это путем сравнения:
if (dstsize > SIZE_MAX >> 1) {
fprintf(stderr, "ft_strlcpy: huge dstsize indicates a negative value was passed: %zd\n", dstsize);
abort();
}
Дело не в этом... дело в том, "как распечатать ошибку ловушки трассировки, когда dstsize является отрицательным числом? (Я знаю, что он будет преобразован в максимальное число size_t.)"
@jyoung, как упоминалось несколько раз, dstsize
— это беззнаковое значение. Оно не может быть отрицательным.
Ага. после -1 конвертировать в максимальное число size_t, это то же самое, что и максимальное число size_t в dstsize. когда это происходит, как распечатать ошибку ловушки трассировки, как исходную функцию?
спасибо за дополнительный ответ. так это единственный способ напечатать ошибку с функцией прерывания? Я думаю, что «SIGABORT» — это не тот же знак «SIGTRAP» (OS X) или «SIGILL» (LINUX).
@jyoung: вы можете отправить сигнал с помощью системного вызова raise
: #include <signal.h> [...] raise(SIGTRAP);
@chqrlie Спасибо за ваш ответ. Это было полезно!
size_t
— беззнаковый тип, поэтому он не может быть отрицательным. Но в любом случае, какое сообщение об ошибке вы ожидаете?