0

strcpyValgrind在以下代码中检测到问题:

#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 的问题。

4

2 回答 2

3

这里:

 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", "123", "def", "456", "ghi", "789"}; 
const int arrLen = sizeof(tempArr) / sizeof(*tempArr) ;
于 2021-06-11T15:30:59.620 回答
0

strcpy(destination, source)。还strcpy() 0- 终止副本。

所以更换

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

经过

  strcpy(array[ii], tempArr[ii]);
于 2021-06-11T15:29:04.947 回答