Valgrind говорит о выделении стека, я говорю о выделении кучи

Я пытаюсь отследить segfault с помощью valgrind. Я получаю следующее сообщение от valgrind:

==3683== Conditional jump or move depends on uninitialised value(s)
==3683==    at 0x4C277C5: sparse_mat_mat_kron (sparse.c:165)
==3683==    by 0x4C2706E: rec_mating (rec.c:176)
==3683==    by 0x401C1C: age_dep_iterate (age_dep.c:287)
==3683==    by 0x4014CB: main (age_dep.c:92)
==3683==  Uninitialised value was created by a stack allocation
==3683==    at 0x401848: age_dep_init_params (age_dep.c:131)
==3683== 
==3683== Conditional jump or move depends on uninitialised value(s)
==3683==    at 0x4C277C7: sparse_mat_mat_kron (sparse.c:165)
==3683==    by 0x4C2706E: rec_mating (rec.c:176)
==3683==    by 0x401C1C: age_dep_iterate (age_dep.c:287)
==3683==    by 0x4014CB: main (age_dep.c:92)
==3683==  Uninitialised value was created by a stack allocation
==3683==    at 0x401848: age_dep_init_params (age_dep.c:131)

Однако вот оскорбительная строка:

 /* allocate mating table */
  age_dep_data->mtable = malloc (age_dep_data->geno * sizeof (double *));
  if (age_dep_data->mtable == NULL)
    error (ENOMEM, ENOMEM, nullmsg, __LINE__);
  for (int j = 0; j < age_dep_data->geno; j++)
    {      
 131=>     age_dep_data->mtable[j] = calloc (age_dep_data->geno, sizeof (double));
      if (age_dep_data->mtable[j] == NULL)
 error (ENOMEM, ENOMEM, nullmsg, __LINE__);
    }

Что дает? Я думал, что любой вызов malloc или calloc выделяет место в куче; здесь не выделена другая переменная, верно? Возможно ли, что происходит другое распределение (оскорбительное распределение стека), которое я не вижу?

РЕДАКТИРОВАТЬ: Мое текущее подозрение - это массив, распределенный по стеку: я объявляю указатель на двойной (стек), а затем присваиваю ему результат функции, которая возвращает двойной *. Затем я запоминаю его в заранее отведенное место.

Я не могу memmove, memcpy или назначить переменную стека, а затем надеюсь, что она сохранится, не так ли?


person Joel J. Adamson    schedule 21.04.2010    source источник
comment
Можем ли мы увидеть еще немного кода? Возможно, age_dep.c   -  person eyalm    schedule 22.04.2010


Ответы (3)


Я не знаю, в чем проблема, но

-track-origins=yes 

может помочь получить больше информации о том, на что он жалуется; подробности см. в этом сообщении в блоге: http://blog.mozilla.com/nnethercote/2009/02/27/eliminating-undefined-values-with-valgrind-the-easy-way/

person Vicky    schedule 21.04.2010
comment
Я использую трек-происхождение; Я забыл упомянуть об этом. Может ли это ввести меня в заблуждение? - person Joel J. Adamson; 21.04.2010

Возможная причина:
вы определяете age_dep_data->mtable как double*, но double** должно быть массивом массивов

person Oleg Razgulyaev    schedule 21.04.2010
comment
Это то, что я делаю? Я выделяю массив размера n*(размер двойного указателя), затем для каждого указателя в этом массиве я выделяю массив размера m*(размер двойного). Нужно ли использовать sizeof(double **) при вызове malloc()? - person Joel J. Adamson; 21.04.2010
comment
нет, ваш код в порядке; мы не видим объявление age_dep_data-›mtable — оно должно быть объявлено как double** - person Oleg Razgulyaev; 21.04.2010
comment
Он объявлен как двойной ** внутри структуры (также динамически выделяемой). - person Joel J. Adamson; 21.04.2010

С тех пор я обнаружил, что эта ошибка valgrind

Conditional jump or move depends on uninitialised value(s)

происходит все время и не является источником ошибки. В большинстве случаев, с которыми я сталкивался после публикации этого вопроса, это кажется отвлекающим маневром.

person Joel J. Adamson    schedule 30.07.2010
comment
Джоэл, нет, это никогда не отвлекающий маневр, и ты всегда должен это исправить. Это потенциально очень серьезная ошибка (хотя иногда и безвредная). - person Nicholas Wilson; 16.03.2013