问题
My code is here:
char* kropecka(char* tab)
{
int a=0,b=0;
char* zwr;
zwr=(char*)malloc(30*sizeof(char));
for(a;strlen(tab);a++)
{
if(tab[a]!='.')
{
if(isupper(tab[a]))
zwr[b]=tolower(tab[a]);
if(islower(tab[a]))
zwr[b]=toupper(tab[a]);
b++;
}
}
zwr[b]='\0';
return zwr;
}
There is no errors, warnings or something like this. But program crashed when I give him some string:
--------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Assertion Failed!
Program: ...s\Visual Studio 2010\Projects\C_homework\Debug\C_homework.exe File: f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c Line: 56
Expression: (unsigned)(c + 1) <= 256
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
--------------------------- Abort Retry Ignore
Compilator: Visual Studio 2010 Included libary: stdio.h, string.h, ctype.h, stdlib.h (for system() function in main() ).
回答1:
This will run forever:
for(a;strlen(tab);a++)
I think you meant:
for(a;a < strlen(tab);a++)
Or better (because strlen
is O(n)):
for(;tab[a];a++)
回答2:
From the C standard:
The header
<ctype.h>
declares several functions useful for classifying and mapping characters. In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.
Emphasis mine.
MSDN's description of toupper() hints at this as well:
In order for toupper to give the expected results, __isascii and isupper must both return nonzero.
isascii():
__isascii returns a nonzero value if c is an ASCII character (in the range 0x00 – 0x7F).
回答3:
The exit test for your loop is wrong. strlen(tab)
will always return either false or true (depending on tab
). This means that you continue writing to zwr
beyond its allocated length. The effects of this are undefined but its not surprising that it eventually crashes.
You can fix this by changing the loop to
for(a;a<strlen(tab);a++)
// ^^
Another possible cause of error is that zwr
is hard-coded as 30 bytes. This clearly isn't sufficient for all possible values of tab
so you could change the code to
size_t len = strlen(zwr)+1;
zwr=malloc(len);
for(;a<len;a++)
回答4:
Check the callstack - hopefully it will take you to the root of the problem.
int __cdecl _chvalidator(
int c,
int mask
)
{
_ASSERTE((unsigned)(c + 1) <= 256);
return ( _pctype[c] & mask);
}
This method looks like one that checks for character value bounds...
isctype.c -
/***
* __chvalidator
*
* Purpose:
* This function is called by character testing functions in debug
* versions. This function test for validation of c as character.
* For improvement in performance, it is not used in non-debug
* version. It is available in the static single-thread non-debug
* build, though, just in case C code that includes ctype.h is compiled
* /D_DEBUG /ML.
*
*******************************************************************************/
In simple terms it seems that you are overflowing on a variable i.e. Unsigned Char can take a maximum value of 255. If you add 1 to an existing value of 255 - you overflow on it.
Hope it helps.
来源:https://stackoverflow.com/questions/15877048/tolower-and-toupper-arent-working