条件跳转或移动取决于 strcpy 处的未初始化值

问题描述

Valgrind 在以下代码中检测到 strcpy 的问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main () {

    char **array;
    int mallocedLen = 15;
    int arrLen = 10;
    char tempArr[20][20] = {"abc","123","def","456","ghi","789"};
    int ii;
    
    array = (char**)malloc(sizeof(char*) * arrLen);
    for(ii = 0; ii < arrLen; ii++){
        array[ii] = (char*)malloc(sizeof(char) * (strlen(tempArr[ii]) + 1));
        strcpy(tempArr[ii],array[ii]);
        array[ii][strlen(tempArr[ii])] = '\0';
        mallocedLen++;
    }
    
    return 0;
}
==4360== Conditional jump or move depends on uninitialised value(s)

==4360== at 0x483F0A2: strcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)

代码似乎编译得很好,所以我认为这不是 malLocing 的问题。

解决方法

这里:

 array[ii] = (char*)malloc(sizeof(char) * (strlen(tempArr[ii]) + 1));
 strcpy(tempArr[ii],array[ii]);

您为 array[ii] 分配空间,然后在它尚未包含有效字符串时立即将其作为源字符串传递给 strcpy()

您似乎有意将 tempArr[ii] 作为来源:

strcpy( array[ii],tempArr[ii] ) ;

并且 nul 终止是不必要的 - strcpy() 已经做到了。

Conditional jump or move depends on uninitialised value(s)

意思就是它所说的。例如 strcpy() 可能有:

while( *source != 0 )
{
    ...
}

但是 *source 尚未初始化,因此循环可能会也可能不会进行迭代。

另请注意,您是否将 tempArr 声明为:

const char* tempArr[] = {"abc","123","def","456","ghi","789"}; 

编译器会发现你的错误。我假设 tempArr 是不可变的?在这种情况下,将其声明为这样。在构建时捕获语义错误总是更好,而不是依赖运行时检测工具。在这种情况下,它的内存效率也更高。

另一个问题是:

for(ii = 0; ii < arrLen; ii++){

其中 arrlen 是 10,但 tempArr 只有 6 个初始化器。最好使用标记值,例如 NULL 或空字符串。或者,如果您使用上面的 const char* tempArr[] 声明,则:

const char* tempArr[] = {"abc","789"}; 
const int arrLen = sizeof(tempArr) / sizeof(*tempArr) ;
,

class ClasUnderTest{ fun method1(){ GlobalScope.launch { myDelayedMethod() } } suspend fun myDelayedMethod(): String{ withContext(dispatchers.default()){ delay(X) ... someClass.someMethod() } } } @Test fun myTest()= coroutinesTestRule.testDispatcher.runBlockingTest { val someClassMock = mock(SomeClass::class.java) val myObject = ClasUnderTest(someClassMock) method1() verify(someClassMock).someMethod() } 。 也strcpy(destination,source) strcpy() - 终止副本。

所以替换

0

  strcpy(tempArr[ii],array[ii]);
  array[ii][strlen(tempArr[ii])] = '\0';