Before me I had a simple task in the given line to insert a number of spaces between words so that the length of the line was 60 characters. But when you start, you get the error "stack around the variable 's' was corrupted". Who can tell what the problem is?

#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; } 
  • What kind of “s” is it if iostream namespace std ? ... - Harry
  • What language is it written in? #include<iostream> is C ++. But in C ++ you can't char*delim = " "; . - AnT
  • @AnT, "But in C ++ you can't char*delim = " "; ". Must be const char *delim = " "; ? - wololo
  • @wololo: Yes, for example. - AnT
  • one
    @wololo: Well, I hope you know that in C ++ 98 / C ++ 03, there was a special conversion from string literal to char * specially for such cases. In C ++ 11, this conversion has been removed, but some compilers still support it in compatibility mode. This, however, is no reason to do so in C ++ code. Yes, and in the C code you should avoid pointing to string literals through char * . And ideone is generally a profanation. coliru.stacked-crooked.com/a/c328322d8058fb56 - AnT

2 answers 2

The debug version of the strcat_s function on each call fills the unused remainder of the buffer with a value of 0xFD , up to the specified size

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

Buffer with 0xFD. To disable this behavior, use _CrtSetDebugFillThreshold.

Therefore, if you “lie” the strcat_s function about the size of your buffer in a big way, then the value 0xFD will be written out of the buffer, even if the lines you connect fit perfectly into the target buffer.

In your code, you obviously "lie" about the size of your buffer: the buffer size is 61 , and you pass the value of sizeof arr[j] to strcat_s , i.e. 130 . The first time strcat_s is called, it destroys the contents of the stack outside s , no matter what your input is.

This behavior of strcat_s made specifically to detect errors like yours as early as possible.

That's all.


PS If you make _CrtSetDebugFillThreshold(0); at the beginning of your program _CrtSetDebugFillThreshold(0); , then the error "disappears", because the actual exit from the buffer in your code (with a "reasonable" input) does not occur. However, this is, of course, a profanation. If you have already begun to use the functions of the _s group, then use them correctly.

PPS Inside the change function, the variable s is of type char * and, accordingly, sizeof(s) is simply the size of the pointer. Therefore your

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

pretty pointless action. It works, but you could just as easily do *s = 0 . The use of memset here does not give anything.

    Look carefully at the gets_s syntax .

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

    there are two parameters, not one. Therefore, you need to call at least so

     gets_s(s, 60); 
    • It is unlikely that his input line is longer than 60 characters ... - Harry
    • it does not matter. It's si, not c ++ :) Although there is a c ++ snuff :) - KoVadim
    • Well yes. With iostream and using namespace... This is C ++ ... And it compiles 100% in C ++ mode. - Harry
    • yes i have seen But where is the use? And the code is written in C. But I have repeatedly noticed from the studio compiler that it does not swear at the lack of parameters in _s functions, but falls as it should be - KoVadim
    • @KoVadim: The studio compiler always regularly complains about missing parameters in _s functions when these parameters are needed. You obviously considered using _s functions in C ++ code, where they were overloaded with templates that substituted for the missing parameters. - AnT