Вайн,
Geekoaur хорошо ответил на ваш вопрос, я просто указываю на еще одну «проблему» с вашим кодом.
Строка s1[strlen(s1)] = '\0';
является no-op, если s1
уже корректно завершается нулем ДО того, как она будет выполнена.
Но если s1
НЕ уже правильно завершается нулем ДО того, как эта строка будет выполнена (и вам не повезло), это вызовет:
Это связано с тем, что strlen
в основном находит индекс существующего нулевого терминатора и возвращает его! Вот правильная, неоптимизированная реализация strlen:
int strlen(char *string) {
int i = 0;
while(string[i] != '\0') {
++i;
}
return i;
}
Итак... Если вы ДЕЙСТВИТЕЛЬНО беспокоитесь о том, что строки НЕ заканчиваются нулем, вы должны сделать что-то вроде:
string[sizeof(string)]='\0';
для локальных автоматических строк (где компилятор "знает" размер строки);
- или
string[SIZE_OF_STRING]
для всех других строк, где SIZE_OF_STRING
(чаще всего) представляет собой константу #define
или переменную, которую вы поддерживаете специально для хранения текущего размера (а не длины) динамически выделяемой строки.
И если вы ДЕЙСТВИТЕЛЬНО, ДЕЙСТВИТЕЛЬНО, ДЕЙСТВИТЕЛЬНО беспокоитесь о том, что строки не заканчиваются нулем (например, вы имеете дело с «грязными» библиотечными методами (например, с ATMI Tuxedo), вы ТАКЖЕ «очищаете» свой «вернуть строки» перед передачей их подозрительным библиотечным методам с помощью:
- до:
memset(string, NULL, SIZE_OF_STRING);
- вызвать:
DirtyFunction(/*out*/string)
;
- после:
string[SIZE_OF_STRING]='\0'
Найти SIG11 очень сложно, потому что (если только вы не «подцепите» их с помощью signal-processor и сказать иначе, они приводят к тому, что Unix принудительно завершает вашу программу, поэтому вы не можете ничего записать (постфактум), чтобы выяснить, где, черт возьми, сделал-это-пришло-от... особенно учитывая, что во многих случаях строка кода, которая выдает SIG11, не является фактической причиной потери строки своего нулевого терминатора.
Это имеет для вас смысл?
Здоровья, приятель. Кейт.
PS: ПРЕДУПРЕЖДЕНИЕ: strncpy
НЕ всегда завершается нулем... вы, вероятно, имели в виду strlcpy
вместо этого. Я усвоил это на собственном горьком опыте... когда рухнул платеж на 60 миллионов долларов.
ИЗМЕНИТЬ:
К вашему сведению: вот «безопасная» (неоптимизированная) версия strlen, которую я назову strnlen
(думаю, она должна быть в stdlib. Эх).
// retuns the length of the string (capped at size-1)
int strnlen(char *string, int size) {
int i = 0;
while( i<size && string[i]!='\0' ) {
++i;
}
return i;
}
person
corlettk
schedule
07.05.2011
delspace
определенно неверна! Это преобразуетabc\0
вbc\0
. - person TrueY   schedule 18.02.2016