当我运行这个可变参数函数时,我收到警告array subscript has type 'char'
,然后它崩溃了。我怀疑问题发生在while
循环的某个地方。我已经尝试了很多方法来防止这个函数崩溃。例如:我尝试将(argp, char)
更改为(argp, int)
,但这不会产生正确的输出。我也不允许改变原型功能。请帮忙!
char fancyMostFrequentChar(char c, ...) {
char j;
int max = 0;
int fre[255] = { 0 };
char temp;
va_list argp;
if (c == '\0')
return '\0';
va_start(argp, c);
//This for loop will run through the arguments
//and record their frequencies into fre[] array
while ((temp = va_arg(argp, char)) != '\0') {
++fre[temp];
if (fre[temp] > max) {
max = fre[temp];
j = temp;
}
}
va_end(argp);
return j;
}
答案 0 :(得分:2)
你绝对应该temp
unsigned char
或使用强制转换来使用它来索引数组fre
。默认情况下,char
可以并且通常是签名的,因此任何负值都可以访问数组边界之外。顺便说一句,您应该将fre
一个项目放大,以适应所有8位值,包括255
。
请注意,您不计算第一个参数,因此fancyMostFrequentChar('a', 'b', 'a', '\0')
将返回'b'
而不是'a'
。
另请注意(由M.M评论)第一个参数应定义为int
,va_start
具有已定义的行为:
7.16.1.4
va_start
宏<强>概要强>
#include <stdarg.h> void va_start(va_list ap, parmN);
<强>描述强>
在访问未命名的参数之前,应调用
va_start
宏。
va_start
宏初始化ap
以供va_arg
和va_end
宏后续使用。 [...]参数
parmN
是函数定义中变量参数列表中最右边参数的标识符(就在......之前)。如果使用parmN
存储类,函数或数组类型声明参数register
,或者使用与应用默认参数提升后生成的类型不兼容的类型,则行为char fancyMostFrequentChar(char c, ...)
未定义。
你提到你不应该改变原型......不幸的是,发布char fancyMostFrequentChar(int c, ...) {
int fre[256] = { 0 };
char temp, res = (char)c;
if (res != '\0') {
va_list argp;
va_start(argp, c);
++fre[(unsigned char)res];
//This for loop will run through the arguments
//and record their frequencies into fre[] array
while ((temp = va_arg(argp, char)) != '\0') {
if (++fre[(unsigned char)temp] > fre[(unsigned char)res]) {
res = temp;
}
va_end(argp);
}
return res;
}
的原型不能用于访问第一个之后的参数。
以下是更正后的版本:
@Query("SELECT d FROM Data d WHERE ((?2) IS NULL OR d.categories IN (?2))")
答案 1 :(得分:1)
va_arg(argp, char)
是未定义的行为。 va_arg
宏的使用要求类型在default argument promotions下保持不变 - 这意味着您不能使用float
,也不能使用比int
更窄的任何整数类型。 (字符类型是整数类型)。参考:C11 7.16.1.1/2
将va_start
的第二个参数设置为在默认参数提升下更改的类型,也是未定义的行为。因此,实际上无法正确访问声明为char fancyMostFrequentChar(char c, ...)
的函数的可变参数。
要解决此问题,您必须更改该功能的原型,例如:
char fancyMostFrequestChar(int c, ...)
并且循环的相关部分应为:
int temp;
while ((temp = va_arg(argp, int)) != '\0')
{
unsigned char index = (unsigned char)temp;
然后使用index
作为数组索引。然后保证在1
到UCHAR_MAX
范围内(通常为255
)。对于迂腐的正确性,您可以将数组定义更改为int fre[UCHAR_MAX+1]
。
答案 2 :(得分:0)
你的代码有很多问题,我希望我能抓住所有问题。
unsigned char fancyMostFrequentChar(unsigned char c, ...) // resolve ambigity of char
{
unsigned char j = '\0'; // was not initialized
int max = 0;
int fre[256] = {0}; // max unsigned char is 255 -> array length = 256 (0..255)
unsigned char temp;
va_list argp;
if (c == '\0')
return '\0';
va_start(argp, c);
//This for loop will run through the arguments
//and record their frequencies into fre[] array
while ((temp = va_arg(argp, unsigned char)) != '\0')
{
++fre[temp];
if (fre[temp] > max)
{
max = fre[temp];
j = temp;
}
}
va_end(argp);
return j;
}