簡體   English   中英

導致此C代碼中的分段錯誤錯誤的原因是什么?

[英]What is causing the segmentation fault errors in this C code?

編輯:感謝您的答案到目前為止,至少我現在可以編譯它,但我仍然得到分段錯誤。

對於編譯,我使用以下行:

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

非常感謝,馬庫斯

你的diff函數的簽名是timespec diff(timespec start, timespec end) ,它應該是struct timespec diff(struct timespec start, struct timespec end)


編輯您的差異函數分配給未初始化的結構指針,您可能希望將其更改為類似以下內容。

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

根據您的需要,您可能只想生成經過的時間,如下所示:

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

您必須在timespec之前添加struct關鍵字。 例如

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

您正在將其編譯為C( gcc.c擴展名),但看起來您正在使用C ++進行編碼(在聲明變量時可以提交struct )。

此外,在C中,我們通常不按值傳遞結構。

另一個提示是始終以高警告級別編譯,至少是-Wall -pedantic ,以便及早發現問題。

我想你想要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全局。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM