条件跳转或移动取决于函数调用中未初始化的值

Conditional jump or move depends on uninitialised value(s) on function call

本文关键字:初始化 函数调用 取决于 移动 条件      更新时间:2023-10-16

我已经处理这个问题一段时间了,我不明白为什么它不起作用。该代码只是用于解决模拟问题的工作程序的扩展。我刚刚在结构中添加了两个字符串变量,还调整了必要的函数,以便移交额外的参数。Valgrind显示大约20种不同的条件跳跃或移动取决于未初始化的值错误。所有这些都提供了相同的错误信息:

Uninitialised value was created by a stack allocation
at 0x401E23: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:360)

以下是各自的功能:

typedef struct tproxel *pproxel;
typedef struct tproxel {
    int     id;                  /* unique proxel id for searching    */
    int     s;                   /* discrete state of SPN             */
    int     tau1k;               /* first supplementary variable      */
    int     tau2k;               /* second supplementary variable     */
    double  val;                 /* proxel probability                */
    string path;                 /* previous path                     */
    string output;               /* previous output                   */
    pproxel left, right;         /* pointers to child proxels in tree */
} proxel;

/* adds a new proxel to the tree */
void addproxel(int s, int tau1k, int tau2k, double val, string &path, string &output) {
    proxel *temp, *temp2;
    int cont = 1,id;
    /* Alarm! TAUMAX overstepped! */
    if (tau1k >= TAUMAX) {
        //  printf(">>> %3d %3d %3d %7.5le n", s, tau1k, val, TAUMAX);
        tau1k = TAUMAX - 1;
    }
        /* compute id of new proxel */
    id = TAUMAX*(TAUMAX*s+tau1k)+tau2k;
    /* New tree, add root */
    if (root[sw] == NULL) {
        root[sw] = insertproxel(s,tau1k, tau2k, val, path, output);
        root[sw]->left = NULL;
        root[sw]->right = NULL;
        return;
    }
    /* Locate insertion point in tree */
    temp = root[sw];    
    while (cont == 1) {
        if ((temp->left != NULL) && (id < temp->id))
            temp = temp->left;
        else
            if ((temp->right != NULL) && (id > temp->id))
                temp = temp->right;
            else
                cont = 0;
    }
    /* Insert left leaf into tree */
    if ((temp->left == NULL) && (id < temp->id)) {
        temp2        = insertproxel(s, tau1k,tau2k, val, path, output);
        temp->left   = temp2;
        temp2->left  = NULL;
        temp2->right = NULL;
        return;
    }
    /* Insert right leaf into tree */
    if ((temp->right == NULL) && (id > temp->id)) {
        temp2        = insertproxel(s, tau1k,tau2k, val, path, output);
        temp->right  = temp2;
        temp2->left  = NULL;
        temp2->right = NULL;
        return;
    }
    /* Proxels have the same id, just add their vals */
    if (id == temp->id) {
        temp->val += val;
        return;
    }
    printf("nnn!!!!!! addproxel failed !!!!!nnn");
}
 /* compute size of tree */
int size(proxel *p) {
    int sl, sr;
    if (p == NULL)
        return(0);
    sl = size(p->left);
    sr = size(p->right);
    return(sl+sr+1);
}

在添加两个字符串变量之前,代码运行得很好,但现在我只遇到了内存访问冲突。经过几个小时的努力,我不知道可能出了什么问题。

我希望有人能告诉我我错过了什么,任何帮助都将不胜感激。

编辑:

我已经把@Jens指出的内容改回了原始程序中的工作代码,现在我得到了不同的错误:

==1900== 1 errors in context 1 of 4:
==1900== Invalid read of size 4
==1900==    at 0x5159218: std::string::assign(std::string const&) (in /usr/lib/libstdc++.so.6.0.13)
==1900==    by 0x401CF1: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:347)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)
==1900==  Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd
==1900== 
==1900== 
==1900== 1 errors in context 2 of 4:
==1900== Use of uninitialised value of size 8
==1900==    at 0x5159218: std::string::assign(std::string const&) (in /usr/lib/libstdc++.so.6.0.13)
==1900==    by 0x401CF1: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:347)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)
==1900==  Uninitialised value was created by a heap allocation
==1900==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==1900==    by 0x401C57: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:336)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)
==1900== 
==1900== 
==1900== 1 errors in context 3 of 4:
==1900== Conditional jump or move depends on uninitialised value(s)
==1900==    at 0x51591A5: std::string::assign(std::string const&) (in /usr/lib/libstdc++.so.6.0.13)
==1900==    by 0x401CF1: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:347)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)
==1900==  Uninitialised value was created by a heap allocation
==1900==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==1900==    by 0x401C57: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:336)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)
==1900== 
==1900== 
==1900== 1 errors in context 4 of 4:
==1900== Conditional jump or move depends on uninitialised value(s)
==1900==    at 0x5159181: std::string::assign(std::string const&) (in /usr/lib/libstdc++.so.6.0.13)
==1900==    by 0x401CF1: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:347)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)
==1900==  Uninitialised value was created by a heap allocation
==1900==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==1900==    by 0x401C57: insertproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:336)
==1900==    by 0x401E48: addproxel(int, int, int, double, std::string&, std::string&) (HNMM.cpp:374)
==1900==    by 0x402195: main (HNMM.cpp:465)

相应的代码和错误产生行:

/* get a fresh proxel and copy data into it */
proxel *insertproxel(int s, int tau1k, int tau2k, double val, string &path, string &output) {
    proxel *temp;
    /* create new proxel or grab one from free list */
  if (firstfree == NULL)
    temp = (proxel*) malloc(sizeof(proxel));
  else {
    temp = firstfree;
    firstfree = firstfree->right;
  }
  /* copy values */
  temp->id    = TAUMAX*(TAUMAX*s+tau1k)+tau2k;
  temp->s     = s;
  temp->tau1k = tau1k;
  temp->tau2k = tau2k;
  temp->val   = val;
  temp->path  = string(path);
  temp->output  = string(output);
  ccpcnt     += 1;
  if (maxccp < ccpcnt) {
      maxccp = ccpcnt;
      //printf("n ccpcnt=%d",ccpcnt);
  }
  return(temp);
}

第336行:

temp = (proxel*) malloc(sizeof(proxel));

347行:

temp->path  = string(path);

第374行:

root[sw] = insertproxel(s,tau1k, tau2k, val, path, output);

insertproxel中,返回对堆栈分配变量的引用:

   proxel temp2 = {0};
   temp = &temp2;
   /* ... */
   return(temp);