Недавно я обнаружил программное обеспечение с открытым исходным кодом , написанное в C, написанное около 20 лет go, и я пытался немного изменить его в соответствии со своими потребностями.
В частности, я пытался запустить программу в al oop так, чтобы она обрабатывала несколько экземпляров решаемой ею задачи одновременно (вместо того, чтобы вызывать ее несколько раз, скажем, с помощью сценария оболочки).
Теперь я должен объявить, что я очень новичок в C (фактически взял C для работы с этим кодом), хотя у меня есть некоторый опыт программирования на языках более высокого уровня, таких как Java, Python и Haskell.
Основная часть вычислений выполняется в подпрограммах, написанных на фортране, а часть C используется для чтения / записи файлов. Я хочу сделать так, чтобы он читал в файле, содержащем несколько экземпляров проблемы, и выводил несколько решений, соответствующих входным экземплярам. Звучит достаточно просто.
Вот l oop, который я придумал (урезанный до того места, где, как мне кажется, ошибки l ie)
while (fgets(smiles, STR_MAX_LENGTH, input) != NULL) {
/*
Allocate memory.
*/
iInd = calloc(numDs, sizeof(int));
jInd = calloc(numDs, sizeof(int));
lbd = calloc(numDs, sizeof(double));
ubd = calloc(numDs, sizeof(double));
n = 3 * numAtoms;
lintWkSp = 2 * numAtoms > numDs ? 2 * numAtoms : numDs;
ldblWkSp = 22 * n + 21;
fOpt = calloc(1, sizeof(double));
dErr = calloc(3, sizeof(double));
xOpt = calloc(n, sizeof(double));
intWkSp = calloc(lintWkSp, sizeof(int));
dblWkSp = calloc(ldblWkSp, sizeof(double));
/*
Call the DG optimizer to obtain a set of solutions.
*/
seed = 1;
for (k = 0; k < numSols; k++) {
/*
Call the DG optimizer.
*/
dginitial(&numAtoms, xOpt, &numDs, iInd, jInd, lbd, ubd, &seed, intWkSp);
dgopt(&numAtoms, xOpt, fOpt, &numDs, iInd, jInd, lbd, ubd, intWkSp, dblWkSp);
dgerr(&numAtoms, xOpt, fOpt, &numDs, iInd, jInd, lbd, ubd, dErr);
}
/*
Clean up.
*/
free(iInd);
free(jInd);
free(lbd);
free(ubd);
free(fOpt);
free(xOpt);
free(dErr);
free(intWkSp);
free(dblWkSp);
}
Суть программы в том, прочитать файл, содержащий расстояния между некоторыми точками пространства, и попытаться найти его 3D-вложение. Я изменил его так, что он будет читать на расстоянии для экземпляра проблемы, разделенных разделителем (я использовал ###
в качестве разделителя), и вызывать подпрограммы Fortran dgopt
для этого экземпляра и выводить решения в другой файл, повторяя, пока не будет использован весь файл.
Теперь о проблеме: кажется, что проблемы не решаются правильно, когда я помещаю их в al oop, как это. Некоторые решения кажутся неправильными и дают нереалистичные c ошибки: однако они работают правильно, когда я проверяю их в исходной версии программы (также работает правильно, когда я выделяю их и запускаю свою версию, но только в этом случае) - указывая Я что-то сломал при попытке сделать несколько экземпляров в al oop. В конечном счете, я думаю, что с l oop я не даю каждому экземпляру одинаковые начальные условия для каждого запуска, как это было бы в исходной версии.
Я думал, что это могло быть связано с работой оптимизатора на массивах, с которыми уже работал предыдущий экземпляр, поэтому я попытался убедиться, что этого не произойдет, используя calloc
вместо malloc
, что инициализирует их все как 0
. Похоже, это не помогло исправить ситуацию, так как теперь программа не будет работать полностью - давая мне free(): invalid next size (fast)
, как в заголовке.
Ошибка с free
, по-видимому, возникает с intWkSp
и dblWkSp
массивов, и ошибка возникает, когда экземпляры на входе имеют переменные размеры (numDs
), где intWkSp
часто терпит неудачу, когда предыдущий экземпляр проблемы был больше текущего - он работает правильно (оптимизатор dgopt
дает правильное значение ответы также) подавляющее большинство случаев, когда все экземпляры на входе имеют одинаковый размер.
Возможно, две проблемы (оптимизатор dgopt
дает неправильный ответ, а за ними следует проблема с free
) связаны?
Я понимаю, что, возможно, допустил много ошибок, поскольку не очень много знаю C - пожалуйста, если у вас есть какие-либо комментарии по поводу моего кода стилистически, я также хотел бы услышать их:)
Вот полная версия кода, который заменяет файл ./dgsol_s/dgsol.c
(я думаю, что было бы слишком долго и, вероятно, не слишком полезно вставлять сюда, но на всякий случай ошибки были не в тех частях, которые я выделил)