Что вызывает ошибки ошибки сегментации в этом коде C? - PullRequest
3 голосов
/ 27 января 2010

РЕДАКТИРОВАТЬ: Спасибо за ответы, по крайней мере, я могу скомпилировать его сейчас, но я все еще получаю ошибку сегментации.

Для компиляции я использую следующую строку:

gcc -g -O0 -I../include -L../ test.c -static -lrt

Исходный код выглядит следующим образом:

#include <sys/time.h>
#include <time.h>
#include <stdio.h>


struct timespec *diff(struct timespec *start, struct timespec *end);

int main()
{
struct timespec time1, time2;
    int i;
int temp = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
for (i = 0; i< 242000000; i++)
    temp+=temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
    printf("sec: %d, nsec: %f",diff(&time1,&time2)->tv_sec,    diff(&time1,&time2)->tv_nsec);
//cout<<diff(time1,time2).tv_sec<<":"<<diff(time1,time2).tv_nsec<<endl;
return 0;
}

struct timespec *diff(struct timespec *start, struct timespec *end)
{
struct timespec *temp;
if ((end->tv_nsec-start->tv_nsec)<0) {
    temp->tv_sec = end->tv_sec-start->tv_sec-1;
    temp->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
} else {
    temp->tv_sec = end->tv_sec-start->tv_sec;
    temp->tv_nsec = end->tv_nsec-start->tv_nsec;
}
return temp;
}

Теперь я получаю следующее предупреждение:

test.c: In function ‘main’:
test.c:17: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘__time_t’
test.c:17: warning: format ‘%f’ expects type ‘double’, but argument 3 has type ‘long int’

Ошибка сегментации, безусловно, вызвана моей обработкой структур. Давненько мне приходилось иметь дело с Си ....

Большое спасибо, Marcus

Ответы [ 5 ]

3 голосов
/ 27 января 2010

В зависимости от ваших потребностей, вы можете просто сгенерировать прошедшее время следующим образом:

double t_ns = (double)(end.tv_sec - start.tv_sec) * 1.0e9 + (double)(end.tv_nsec - start.tv_nsec); // get elapsed time in ns

Кроме того, FWIW, я использую CLOCK_PROCESS_CPUTIME_ID - кажется, он дает лучшую точность и разрешение на различных системах на базе Linux, на которых я пробовал:

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);

// ... stuff ... //

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

3 голосов
/ 27 января 2010

Подпись вашей функции сравнения timespec diff(timespec start, timespec end), где она должна быть struct timespec diff(struct timespec start, struct timespec end).


EDIT Ваша функция сравнения присваивает неинициализированный указатель структуры, вы можете изменить его на что-то вроде следующего.

void diff(struct timespec *start, struct timespec *end,
    struct timespec *result);

int main()
{
    struct timespec time1, time2, result;
    int i;
    int temp = 0;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
    for (i = 0; i< 242000000; i++)
        temp+=temp;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

    diff(&time1, &time2, &result);

    printf("sec: %ld, nsec: %ld", (long int)result.tv_sec,
        (long int)result.tv_nsec);
    return 0;
}

void diff(struct timespec *start, struct timespec *end,
    struct timespec * result)
{
    if ((end->tv_nsec-start->tv_nsec)<0) {
        result->tv_sec = end->tv_sec-start->tv_sec-1;
        result->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
    } else {
        result->tv_sec = end->tv_sec-start->tv_sec;
        result->tv_nsec = end->tv_nsec-start->tv_nsec;
    }
}
0 голосов
/ 27 января 2010

Я думаю, вы хотите, чтобы diff () возвращала динамически или статически размещенный указатель.

Попробуйте (предложения в комментариях):

struct timespec *diff(struct timespec *start, struct timespec *end)
{
struct timespec *temp;

/* allocate temp to be sizeof(struct timespec) and zero it out */
temp = malloc(sizeof(struct timespec));
/* Of course, deal with malloc (or calloc) failing */
memset(tmp, 0, sizeof(struct timespec));

if ((end->tv_nsec-start->tv_nsec)<0) {
    temp->tv_sec = end->tv_sec-start->tv_sec-1;
    temp->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
} else {
    temp->tv_sec = end->tv_sec-start->tv_sec;
    temp->tv_nsec = end->tv_nsec-start->tv_nsec;
}
return temp;
/* Make sure caller frees the returned pointer */
}

Если динамическое распределение является табу, то:

static struct timespec temp;
/*zero it out, watch concurrency too! */

....

temp.tv_sec = end->tv_sec-start->tv_sec;
/* Make sure caller does NOT free (or modify) the pointer */
return temp;

Вам необходимо вернуть указатель (как бы он ни был выделен), который действительно может быть достигнут вызывающим. Или сделайте * temp глобальным.

0 голосов
/ 27 января 2010

Вы компилируете его как C (расширение gcc и .c), но похоже, что вы кодируете в C ++ (где struct может быть зафиксировано при объявлении переменных).

Кроме того, в Си мы обычно не передаем структуры по значению.

Еще один совет - всегда компилировать с высоким уровнем предупреждения, по крайней мере, -Wall -pedantic, для раннего обнаружения проблем.

0 голосов
/ 27 января 2010

Вы должны добавить ключевое слово struct перед указанием времени. Например.

struct timespec diff(struct timespec start, struct timespec end);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...