переназначение значения, возвращаемого функцией, вызывает ошибку сегмента - PullRequest
0 голосов
/ 29 июля 2011

У меня есть код LDA на C, который я пытаюсь отлаживать, и я уже довольно долго бьюсь головой.

lda_model *model = NULL;
model = malloc(sizeof(lda_model));
model = quiet_new_lda_model(corpus->num_terms, NTOPICS);
printf ("%f\n", model->alpha); // Segfaults here

если мы посмотрим на функцию создания модели

lda_model* quiet_new_lda_model(int num_terms, int num_topics) {
    int i;
    lda_model* model;

    model = malloc(sizeof(lda_model));
    model->num_topics = num_topics;
    model->num_terms = num_terms;
    model->alpha = 1.0;
    printf ("%f\n", model->alpha); // Prints 1.0
    model->log_prob_w = malloc(sizeof(double*)*num_topics);
    for (i = 0; i < num_topics; i++)
    {
        model->log_prob_w[i] = malloc(sizeof(double)*num_terms);
    memset(model->log_prob_w[i],0,sizeof(double)*num_terms);
    }
    printf ("%f\n", model->alpha); // Prints 1.0
    return(model);
}

В чем может быть проблема при транзакции между функцией quiet_new_lda_model и исходным вызывающим абонентом?

Спасибо!

Ответы [ 5 ]

5 голосов
/ 29 июля 2011

Ну, во-первых, malloc в вызывающей программе не нужен и вызывает утечку памяти.Попробуйте заменить эти четыре строки на

lda_model *model = quiet_new_lda_model(corpus->num_terms, NTOPICS);
printf ("%f\n", model->alpha); // Segfaults here

Но это вряд ли станет причиной ошибки сегмента.Следующее, что я хотел бы спросить, является ли прототип quiet_new_lda_model видимым в вызывающей программе?Если нет, ваш указатель может быть усечен до int.Это можно узнать, изменив все три строки printf на

printf("%p\n", model);

. Если третья строка printf печатает значение, отличное от первых двух, вероятно, проблема в отсутствующем прототипе.

РЕДАКТИРОВАТЬ: Еще один способ определить, есть ли у вас отсутствующий прототип, - это просмотреть предупреждающие сообщения, подобные этому:

test.c:4: warning: initialization makes pointer from integer without a cast

Фразировка может отличаться в зависимости от контекста и от того, какой компилятор вы используете.повторное использование.Если вы используете GCC, используйте ключ командной строки -Wall, чтобы получить более сильный намек:

test.c:4: warning: implicit declaration of function ‘quiet_new_lda_model’
test.c:4: warning: initialization makes pointer from integer without a cast

«Неявное объявление» означает «вы ничего не сказали мне об этой функции, поэтому япредполагается, что он принимает произвольное количество параметров и возвращает int. "Как вы можете себе представить, это почти всегда неправильно.

(Как правило, если вы используете GCC, вы должны всегда иметь -Wall в командной строке.)

1 голос
/ 29 июля 2011

Это не решение, но у вас есть утечка памяти; Вы не должны размещать модель в первом блоке кода, так как она размещена в функции.

Я подозреваю, что настоящая основная причина - это то, что предлагает @Zack - у вас нет прототипа, поэтому возвращаемый адрес становится усеченным (я предполагаю, что вы работаете в 64-битной системе).

использовать

lda_model* quiet_new_lda_model(int, int); 

вверху вашего первого блока кода.

0 голосов
/ 29 июля 2011

Исправьте очевидную ошибку в коде.У вас утечка памяти, которую нужно исправить.Во-вторых, чтобы снова отладить ваш код, в вышестоящей функции выполните такой код if (model) printf ("% f", model-> alfa);Должно помочь вам двигаться вперед.Это невозможно предсказать, но, иногда, утверждение стека может создать ошибку сегмента.

Обновление: попробуйте использовать «% ld» вместо «% f» для изменения.

0 голосов
/ 29 июля 2011

Вы недавно изменили определение lda_model?Вы перекомпилировали все исходные файлы, которые используют его после изменения?

0 голосов
/ 29 июля 2011

Прежде всего, происходит утечка памяти, выполняющая malloc в функции quiet_new_lda_model без освобождения ранее заявленного ресурса.Вам не нужно делать malloc в вызывающей стороне.Во-вторых, где / как определяется lda_model?Включен ли заголовочный файл в файл, где вы вызываете функцию?

...