2010-01-27 3 views
3

EDIT: Спасибо за ответы до сих пор, по крайней мере, я могу скомпилировать его сейчас, но я все еще получаю ошибку сегментации.Что вызывает ошибки ошибки сегментации в этом коде на C?

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

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’ 

вина Сегментация является, несомненно, вызванное моей обработкой структур. Это довольно давно, что я в последний раз приходилось иметь дело с C ....

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

+0

Попробуйте запустить 'gcc -C -E foo.c' и посмотреть, как определена структура timespec, если она определена вообще. По крайней мере, по Cygwin, у меня есть только «timeval» и «timepec». – csl

+0

Добавьте -Wall к параметрам компилятора. GCC сказал бы вам, в чем проблема: –

ответ

3

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


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

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

Спасибо, сейчас он компилируется. Единственная проблема, которая остается в том, что выходное значение составляет 0 секунд и 0,00000 наносекунд. Существует определенно что-то не так ... – Marcus

+1

@Marcus: убедитесь, что ваш printf верен - если вы используете% f вместо% ld, вы получите значение 0.0000 вместо правильного значения –

0

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

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

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

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

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

0

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

Try (предложения в комментариях):

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 global.

3

В зависимости от ваших потребностей, вы можете просто хотите, чтобы генерировать истекшее время, как это:

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);