【问题标题】:Error: Conditional jump or move depends on uninitialised value - C valgrind错误:条件跳转或移动取决于未初始化的值 - C valgrind
【发布时间】:2017-01-11 23:32:48
【问题描述】:

我是 C 新手,遇到了一个常见问题,但我真的无法理解我的情况的原因。

我有这个方法,其目的是用指定的名称初始化一个 Map 并检查它是否存在于红黑树中。

void reduceMap(char *mapName){

    Map *tempMap = (Map *) malloc(sizeof(Map));
    struct rbNode *tempNode = (struct rbNode *) malloc(sizeof(struct rbNode));

    copyName = stringCopy(mapName);

    tempMap->name = copyName;
    tempNode->data = tempMap;

    ...DO SEARCH HERE...

    freeMap(tempNode);

}

所以我为包含 Map 的节点分配内存,进行研究并最终释放创建的临时对象的内存。我的对象的结构如下:

typedef struct{
    char *name;
    char *specification;
    Point *start, *end;
}Map;

struct rbNode{
    Color color;
    void *data;
    struct rbNode *parent, *leftChild, *rightChild;
};

方法stringCopy和freeMap分别是:

void freeMap(struct rbNode *node){
    if(node){

         free( ((Map *)node->data)->name );

         if(((Map *)node->data)->specification != NULL) 
             free( ((Map *)node->data)->specification );        

         free( (Map *)node->data );
         free(node);
     }
 }


 char *stringCopy(const char *source){
     char *copy = (char *)malloc(strlen(source) + 1);

     strcpy(copy,source);
     return copy;
 }

我正在使用 valgrind 测试程序,这是我得到的错误:

Conditional jump or move depends on uninitialised value(s)
==5215==    at 0x8049DF3: freeMap (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi)
==5215==    by 0x8048C40: reduceMap (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi)
==5215==    by 0x80489DA: main (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi)
==5215==  Uninitialised value was created by a heap allocation
==5215==    at 0x402C17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5215==    by 0x8048B0A: reduceMap (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi)
==5215==    by 0x80489DA: main (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi)

我知道问题是由 tempMap 的分配引起的,似乎有一些东西没有初始化 int 但为什么呢?我只关心名称和规格……我真的不明白。

任何帮助将不胜感激。 谢谢

【问题讨论】:

  • 注意:C 不支持方法,只支持函数。而且你不应该投射malloc 和朋友的结果。
  • 感谢@Olaf 指出这一点

标签: c valgrind


【解决方案1】:

简单地说,似乎在你的reduceMap,发生了这种情况

Map *tempMap = (Map *) malloc(sizeof(Map));
tempMap->name = copyName;
tempMap->specification = /* what!?? */;

您没有初始化整个分配的struct。考虑编写一个映射构造函数(以initMap 函数的形式)来匹配你的析构函数(freeMap)。

旁注Don't cast the result of malloc.

【讨论】:

  • 感谢@StoryTeller 的留言。我认为结构中 char *specification 的默认值自动为 NULL,并且使用 NULL 评估 (Map *)node->data)->specification 不是问题
  • @VeVeVez,这不是必需的。简单地说,它的价值是未指定的。依赖它是任何东西,依赖于未定义的行为。遗憾的是,许多调试器可能会在某些构建配置下将内存初始化为零,从而使这些错误难以跟踪。
【解决方案2】:

您没有在映射中初始化规范成员

typedef struct{
    char *name;
    char *specification;
    Point *start, *end;
} Map;

但是稍后你使用这个未初始化的值来有条件地跳转(if 语句):

if(((Map *)node->data)->specification != NULL)

解决方案

在使用Map 的所有成员之前对其进行初始化。

【讨论】:

  • 谢谢@where_is_tftp,所以如果我理解重点是我必须初始化我计划在我的免费函数中使用/评估的每个字段。我认为结构中char *specification 的默认值自动为NULL,并且用NULL 评估(Map *)node->data)->specification 不是问题......我的错
  • @VeVeVez 在 C 中使用未初始化的变量是未定义的行为。记住这条规则。在 C 中分配在堆上的变量和局部变量一样是未初始化的。您必须在使用前对其进行初始化。
猜你喜欢
  • 2021-03-02
  • 2011-05-06
  • 2011-12-09
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
相关资源
最近更新 更多