我正在维护一些遗留代码中的以下函数。
long getMaxStart(long start, long count, const myStruct *s1, ...)
{
long i1, maxstart;
myStruct *s2;
va_list marker;
maxstart = start;
/*BUGFIX: 003 */
/*(va_start(marker, count);*/
va_start(marker, s1);
for (i1 = 1; i1 <= count; i1++)
{
s2 = va_arg(marker, myStruct *); /* <- s2 is assigned null here */
maxstart = MAX(maxstart, s2->firstvalid); /* <- SEGV here */
}
va_end(marker);
return (maxstart);
}
当仅使用一个myStruct参数调用该函数时,它会导致SEGV。当我使用VS2005编译它时,代码编译并运行而不会在Windows XP上崩溃。我现在已经将代码移动到Ubuntu Karmic,我在Linux上遇到了更严格的编译器问题。是否有人能够在var_arg()语句中找到导致参数无法正确读取的原因?
我正在使用gcc版本4.4.1进行编译
修改
导致SEGV的陈述是这样的:
start = getMaxStart(start, 1, ms1);
当代码执行首次到达此行时,变量'start'和'ms1'具有有效值。
答案 0 :(得分:4)
如上所述,当您只传入一个myStruct
参数时,s1
绑定到该参数,而您的va_list
将为空。然后,你在循环中做的第一件事是从该空列表中获取参数,因此为NULL。
如果您需要至少一个参数并希望编译器为您进行类型检查,则必须执行以下操作:
long getMaxStart(long start, long count, const myStruct *s1, ...) {
...
va_start(marker, s1);
maxstart = s1->firstvalid; /* actually use s1 this time! */
for (i1 = 1; i1 < count; i1++) /* different from your code */
{
...
}
...
}
否则,你最好从功能定义中删除s1
,如Potatoswatter所述:
long getMaxStart(long start, long count, ...) {
...
va_start(marker, count); /* not a bug */
maxstart = -1; /* pick something resonable for your app */
for (i1 = 0; i1 < count; i1++)
{
...
}
...
}
答案 1 :(得分:1)
s1
未被使用有点可疑。 count
是否包含s1
,即传入的指针总数?也许您想要消除s1
并使用va_start(marker, count)
。
编辑:鉴于评论中的澄清,修复肯定是
long getMaxStart(long start, long count, /* const myStruct *s1, */ ...)
{
long i1, maxstart;
myStruct *s2;
va_list marker;
maxstart = start;
va_start(marker, count);
for (i1 = 1; i1 <= count; i1++)
{
s2 = va_arg(marker, myStruct *);
maxstart = MAX(maxstart, s2->firstvalid);
}
va_end(marker);
return (maxstart);
}
遗留代码使用s1
来阐明...
的含义,但由于它干扰了varargs的操作,因此您需要对其进行评论。
答案 2 :(得分:0)
va_start
在变量参数开始之前接受va_list
参数和最后一个参数。您可以调用va_arg
来获取在va_start
中指定的参数之后的第一个参数,或者在上一次调用va_arg
之后的下一个参数。在你的情况下,你告诉它s1
是va_start(marker, s1)
的可变参数之前的最后一个参数,所以当你调用va_arg
时,它会尝试得到 4th < / em>函数调用的参数,但没有第4个,所以你得到了一些奇怪的行为。
您过早地调用va_arg
因为如果为1
参数提供count
,它仍将进入循环,即使您没有足够的参数。你应该使用:
for (i1 = 1; i1 < count; i1++)
但是,如果这样做,则永远不会使用值s1
。与Karmastan的答案一起去。