1. Я написал следующий код, который компилируется, но дает сбой во время выполнения, показывая «Запись нарушения прав доступа» при вызове _tcsset .

void function(TCHAR *tsatz)
{
    printf( "Before: %s\n", tsatz );
    _tcsset(tsatz,'*');
    printf( "After: %s\n", tsatz );
}

void main( void )
{
    TCHAR* tsatz;
    tsatz = new char[256];
    tsatz = "This is a test string ";
    function(tsatz);
    getchar();
}

В чем я ошибаюсь при использовании _tcsset?

2. Я знаю, что все " безопасные " функции работают, если мы сообщаем им размер целевого буфера. Но если мне нужно использовать _tcsset_s в «функции», где цац исходит от внешнего источника, есть ли способ?

Я начинающий. Любая помощь, которую я мог получить, очень ценится. Заранее спасибо.

1
Vik 26 Окт 2015 в 12:08

2 ответа

Лучший ответ

Вы изменяете строковый литерал, это неопределенное поведение.

tsatz = "This is a test string ";

При этом строковый литерал не копируется в tsatz, он просто назначает tsatz, чтобы он указывал на адрес "This is a test string ";, который нельзя изменить . Один из способов обойти это - объявить tsatz как массив и инициализировать его строковым литералом, который автоматически скопирует текст в массив для вас.

TCHAR tsatz[] = "This is a test string ";

Если вам нужно отслеживать размер массива, вам нужно будет сделать это явно (обратите внимание, что sizeof массив будет работать, только если операнд на самом деле является массивом, а не указателем):

void function(TCHAR *tsatz, size_t numberOfElements)
{
    _tprintf( "Before: %s\n", tsatz );
    _tcsset_s(tsatz, numberOfElements, '*');
    _tprintf( "After: %s\n", tsatz );
}

void main( void )
{
    TCHAR tsatz[] = "This is a test string ";
    function(tsatz, sizeof tsatz / sizeof(TCHAR));
    getchar();
}

Или используйте шаблон

template<size_t sz>
void function(TCHAR (tsatz&)[sz])
{
    _tprintf( "Before: %s\n", tsatz );
    _tcsset_s(tsatz, sizeof tsatz / sizeof(TCHAR), '*');
    _tprintf( "After: %s\n", tsatz );
}

Или вы можете просто использовать вместо него std::basic_string.

2
user657267 26 Окт 2015 в 22:25

Проблема с вашим кодом заключается в том, что вы назначаете строку C, доступную только для чтения, переменной-указателю TCHAR* tsatz;; отсюда нарушение доступа.

ВОЗМОЖНОЕ РЕШЕНИЕ:

TCHAR tsatz[256] = "This is a test string ";
function(tsatz);

«_tcsset ()» и его друзья не переносятся; вы вряд ли будете часто встречать их даже в коде только для Windows.

Гораздо лучшим решением, если это возможно для вашего приложения, было бы использование C ++ "std: string".

Например,

std::string tsatz = "This is a test string ";
std::fill(tsatz.begin(), tsatz.end(), '*');
0
paulsm4 27 Окт 2015 в 00:30