C программа повторила mallo c / callo c с последующей ошибкой free: "free (): неверный следующий размер (быстрый)" - PullRequest
0 голосов
/ 19 апреля 2020

Недавно я обнаружил программное обеспечение с открытым исходным кодом , написанное в 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 (я думаю, что было бы слишком долго и, вероятно, не слишком полезно вставлять сюда, но на всякий случай ошибки были не в тех частях, которые я выделил)

...