在地址中使用先前参数时,Sscanf未初始化的值

时间:2016-03-31 18:29:58

标签: c initialization valgrind format-specifiers sequence-points

我正在尝试使用sscanf(在我知道格式良好但不是恶意的字符串上)将值写入数组的特定部分。

#include <stdio.h>
int main(void){
    int arr[10], i;
    sscanf("5 5", "%d %d", &i, arr + i);
}

当我在valgrind中运行时,我被告知sscanf行读取未初始化的值。但是,arr被初始化为指向自动分配的数组的指针,并且i被初始化,因为存在与每个格式说明符相关联的序列点(对于在参数之间没有序列点的一般函数不是这种情况)。我可能倾向于认为这只是发生,因为valgrind不知道格式说明符序列点规则,但在我的完整程序中,该行导致实际的分段错误。为什么会这样?我是否对创建序列点的格式说明符有误?

1 个答案:

答案 0 :(得分:2)

问题在于函数调用的序列点意味着{s}来设置i 的参数计算之前肯定会访问arr + i。所以在初始化之前你正在访问它。

你需要两个sccanf电话;类似的东西:

int len, i;

if (sscanf(buf, "%d%n", &i, &len) >= 1 && sscanf(buf+len, "%d", arr + i) >= 1) {
    // successful sscanf 

请注意,您应始终检查sscanf来电的返回值,看它是否有效。