内存错误未初始化的值与strtol

时间:2017-09-22 18:31:49

标签: c

您好我已经制作了一个测试程序,以便在我对以下代码使用valgrind --track-origins=yes -v ./a.out时获取有关如何解决问题的帮助,它会返回以下错误;

==13192== 1 errors in context 1 of 1:
==13192== Conditional jump or move depends on uninitialised value(s)
==13192==    at 0x4E6CEA6: ____strtol_l_internal (strtol_l.c:438)
==13192==    by 0x4005EB: main (in Desktop/a.out)
==13192==  Uninitialised value was created by a stack allocation
==13192==    at 0x40057D: main (in Desktop/a.out)

这是我的测试程序代码。

char newid[2];
char copyfromid[5] = "12345";

char *test, *extra;
int j, i = 0;

int outputNum;

for (j = 3; j < 5; j++) {
    newid[i] = copyfromid[j];
    i++;
}
test = newid;
outputNum = strtol(test, &extra, 10);
printf("%d", outputNum);

它只是一个测试程序,可以将copyfromid中的最后两个字符转换为一个正在处理的大型项目的数字,任何帮助都会有用,谢谢。

3 个答案:

答案 0 :(得分:1)

  for (j=3;j<5;j++){
        newid[i] = copyfromid[j];
        i++;
    }
newid [i] =0;

您没有添加尾随零,而newid必须至少为3个字符长

答案 1 :(得分:0)

代码中存在一些问题:

  • 使用5字节字符串初始化大小为char的{​​{1}}数组。 null终止符没有空格,生成的代码不会使5成为正确的字符串。
  • 您将copyfromid中的2个字节复制到copyfromid但不会终止newid,这无论如何都太短了。在无效字符串上调用newid具有未定义的行为,这可以解释您的观察结果。

您可以通过这种方式纠正和简化代码:

strtol()

答案 2 :(得分:0)

使用strtol(s, ...)s必须指向字符串newid[]缺少空字符,因此它不是字符串。这会导致未定义的行为,(UB)。

char newid[2];
char *test, *extra;
int j, i = 0;
for (j = 3; j < 5; j++) {
    newid[i] = ...;
    i++;
}
test = newid;
outputNum = strtol(test, &extra, 10);  // ** UB ** , newid is not a string

OP的错误消息提示strtol()正试图走过newid[],因为它会查找要停止的空字符。

  

有条件的跳跃或移动取决于未初始化的值(s)
  == 13192 ==在0x4E6CEA6:____strtol_l_internal(strtol_l.c:438)&#34;

如果代码必须使用缺少空字符的2个字符newid[2],则代码可以使用以下代码。 2限制扫描最多2个字符。

sscanf(newid, "%2d", &outputNum)

@chqrlie

回答了一个坚持字符串的简单好解决方案
char copyfromid[] = "12345";
outputNum = strtol(copyfromid + 2, NULL, 10);