Ошибка Stack around the variable was corrupted

245
04 января 2018, 23:50

Передо мной постала простая задача в заданой строке вставить некоторое количество пробелов между словами чтобы длина строки была 60 символов. Но при запуске выдается ошибка "stack around the variable 's' was corrupted". Кто может подсказать в чем проблема?

 #include "stdafx.h"
 #include<iostream>
 #include<string.h>
 using namespace std;
 void change(char arr[61][130], char s[61], int i) {
 int k = 0;
 while (strlen(s)<60) {
    if (k == i - 1) k = 0;
    strcat_s(arr[k], sizeof arr[k], " ");
    memset(s, 0, sizeof(s));
    for (int j = 0; j < i; j++) 
    strcat_s(s, sizeof arr[j], arr[j]);
    k++;
     }
   printf("%s","A new string: ");
   printf("%s\n", s);
 }
void break_on_array(char s[61]) {
char*p;
char*np = NULL;
char*delim = " ";
int i = 0;
char arr[61][130];
p = strtok_s(s, delim, &np);
while (p != NULL) {
    strcpy_s(arr[i], sizeof arr[i], p);
    p = strtok_s(NULL, delim, &np);
    i++;
   }
    change(arr, s, i);
}
int main()
{
 setlocale(LC_ALL, "rus");
 char s[61];
 printf("%s\n", "Введите строку: ");
 gets_s(s);
 break_on_array(s);
 return 0;
}
Answer 1

Отладочная версия функции strcat_s при каждом вызове заполняет неиспользованный остаток буфера значением 0xFD, вплоть до указанного размера

https://msdn.microsoft.com/en-us/library/d45bbxx4.aspx

The debug versions of these functions first fill the buffer with 0xFD. To disable this behavior, use _CrtSetDebugFillThreshold.

Поэтому если вы "наврете" функции strcat_s про размер вашего буфера в большую сторону, то произойдет запись значения 0xFD за пределы буфера, даже если соединяемые вам строки прекрасно помещаются в целевой буфер.

У вас в коде вы явно "врете" про размер вашего буфера: размер буфера равен 61, а вы передаете в strcat_s значение sizeof arr[j], т.е. 130. При первом же вызове strcat_s происходит уничтожение содержимого стека за пределами s, независимо от того, какие у вас входные данные.

Такое поведение strcat_s сделано специально для того, чтобы как можно раньше выявлять ошибки, вроде вашей.

Вот и все.

P.S. Если вы в начале вашей программы сделаете _CrtSetDebugFillThreshold(0);, то ошибка "исчезнет", ибо фактического выхода за пределы буфера в вашем коде (при "разумном" входе) не происходит. Однако это, разумеется, профанация. Если уже вы взялись пользоваться функциями группы _s, то пользуйтесь ими правильно.

P.P.S. Внутри функции change переменная s имеет тип char * и, соответственно, sizeof(s) является просто размером указателя. Поэтому ваше

memset(s, 0, sizeof(s));

довольно бессмысленное действие. Это "работает", но с таким же успехом можно было сделать просто *s = 0. Применение memset тут не дает ничего.

Answer 2

Посмотрите внимательно на синтаксис gets_s

char *gets_s( char *str, rsize_t n );

там два параметра, а не один. Поэтому, вызывать нужно хотя бы так

gets_s(s, 60);
READ ALSO
Алгоритм Сортировки Слиянием на C++

Алгоритм Сортировки Слиянием на C++

Задача такая, реализовать алгоритм сортировки слияния, прочитав варианты реализации на других сайтах и версию вики, реализация показалась...

215
Socket чтение buffer

Socket чтение buffer

Здравствуйте! Я в c++ новичок и у меня возникла проблема, не знаю как прочитать ответ из буфера socket сервера

163
Перегруженные конструкторы?

Перегруженные конструкторы?

В заголовочном файле:

186
Задача для прокачки мозгов (IQ) [требует правки]

Задача для прокачки мозгов (IQ) [требует правки]

Имеется массив с положительными элементами (N элементов)Районном называется отрезок (l, r) (использовать нужно K районов, ни меньше ни больше),...

224