分割错误(核心转储)C编程pthreads直方图

问题描述:

我使用pthreads做了Histogram,经过长时间的努力后..最后它说'Segmentation Fault(Core Dumped)'。不幸的是我有这条线p =(struct1 *)malloc(sizeof(struct1));从命令行获得值的结构变量..所以这被清除了..感谢@DNT让我知道..分割错误(核心转储)C编程pthreads直方图

现在,当我尝试执行下列程序..它有时会显示输出,有时它会发送到which_bin函数并打印以下内容:

输出类型1(这不是正确的输出): Data = 0.000000不属于bin! 退出

输出型2(几乎HISTO的正确的输出随时间通过螺纹采取): 10.000-28.000: 28.000-46.000: 46.000-64.000: 64.000-82.000: 82.000-100.000:XXXXXXXXXX 该代码将定时把0.000415秒

我的疑问句的是,为什么同样的前卫跑时表现出不同的输出..我很困惑的其所以然寻找..

这里是我的代码..

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include "timer.h" 
void Usage(char prog_name[]); 



//void Get_args(void *p); 
void Gen_data(void *p); 
void Gen_bins(void *p); 
int Which_bin(void *p); 
void Print_histo(void *p); 


void func(void *p); 

struct test 
{ 
    int bin_count, i, bin; 
    float min_meas, max_meas; 
    float* bin_maxes; 
    int* bin_counts; 
    int data_count; 
    float* data; 
}; 

typedef struct test struct1; 

int main(int argc, char* argv[]) 
{ 
    double start, finish, elapsed; 
    GET_TIME(start); 

    struct1 *p; 
    pthread_t th1, th2, th3; 

    p=(struct1 *)malloc(sizeof(struct1)); 
    if (argc != 5) 
     Usage(argv[0]); 
    p->bin_count = strtol(argv[1], NULL, 10); 
    p->min_meas = strtof(argv[2], NULL); 
    p->max_meas = strtof(argv[3], NULL); 
    p->data_count = strtol(argv[4], NULL, 10); 

    p->bin_maxes = malloc(p->bin_count*sizeof(float)); 
    p->bin_counts = malloc(p->bin_count*sizeof(int)); 
    p->data = malloc(p->data_count*sizeof(float)); 


    pthread_create(&th1,NULL,(void*) Gen_data,(void*) p); 
    pthread_create(&th2,NULL,(void*) Gen_bins,(void*) p); 
    pthread_create(&th3,NULL,(void*) func,(void*) p); 
    printf("Hi\n"); 


    pthread_join(th1,NULL); 
    pthread_join(th2,NULL); 
    pthread_join(th3,NULL); 


    Print_histo(p); 
    free(p->data); 
    free(p->bin_maxes); 
    free(p->bin_counts); 

    GET_TIME(finish); 
    elapsed = finish - start; 
    printf("The code to be timed took %f seconds\n", elapsed); 
    return 0; 
} /* main */ 

void func(void *p) 
{ 
    int i; 
    struct1 *args; 
    args=(struct1*)p; 

    for (i = 0; i < args->data_count; i++) 
    { 
     args->bin = Which_bin(args); 
     args->bin_counts[args->bin]++; 
    } 

    # ifdef DEBUG 
     printf("bin_counts = "); 
     for (i = 0; i < args->bin_count; i++) 
      printf("%d ", args->bin_counts[i]); 
     printf("\n"); 
    # endif 
} 

/*--------------------------------------------------------------------- 
* Function: Usage 
* Purpose: Print a message showing how to run program and quit 
* In arg: prog_name: the name of the program from the command line 
*/ 
void Usage(char prog_name[] /* in */) 
{ 
    fprintf(stderr, "usage: %s ", prog_name); 
    fprintf(stderr, "<bin_count> <min_meas> <max_meas> <data_count>\n"); 
    exit(0); 
} /* Usage */ 


void Gen_data(void *p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    int i; 
    srandom(0); 
    for (i = 0; i < args->data_count; i++) 
     args->data[i] = args->min_meas + (args->max_meas - args->min_meas)*random()/((double) RAND_MAX); 

    #ifdef DEBUG 
     printf("data = "); 
     for (i = 0; i < args->data_count; i++) 
      printf("%4.3f ", args->data[i]); 
     printf("\n"); 
    #endif 
} /* Gen_data */ 


void Gen_bins(void* p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    float bin_width; 
    int i; 
    bin_width = (args->max_meas - args->min_meas)/args->bin_count; 

    for (i = 0; i < args->bin_count; i++) 
    { 
     args->bin_maxes[i] = args->min_meas + (i+1)*bin_width; 
     args->bin_counts[i] = 0; 
    } 

    # ifdef DEBUG 
     printf("bin_maxes = "); 
     for (i = 0; i < args->bin_count; i++) 
      printf("%4.3f ", args->bin_maxes[i]); 
     printf("\n"); 
    # endif 
} 

int Which_bin(void* p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    int bottom = 0, top = args->bin_count-1; 
    int mid; 
    float bin_max, bin_min; 

    while (bottom <= top) 
    { 
     mid = (bottom + top)/2; 
     bin_max = args->bin_maxes[mid]; 
     bin_min = (mid == 0) ? args->min_meas: args->bin_maxes[mid-1]; 
     if (*(args->data) >= bin_max) 
      bottom = mid+1; 
     else if (*(args->data) < bin_min) 
      top = mid-1; 
     else 
      return mid; 
    } 
    fprintf(stderr, "Data = %f doesn't belong to a bin!\n", args->data); 
    fprintf(stderr, "Quitting\n"); 
    exit(-1); 
} 

void Print_histo(void *p) 
{ 
    struct1 *args; 
    args=(struct1*)p; 
    int i, j; 
    float bin_max, bin_min; 

    for (i = 0; i < args->bin_count; i++) 
    { 
     bin_max = args->bin_maxes[i]; 
     bin_min = (i == 0) ? args->min_meas: args->bin_maxes[i-1]; 
     printf("%.3f-%.3f:\t", bin_min, bin_max); 
     for (j = 0; j < args->bin_counts[i]; j++) 
      printf("X"); 
     printf("\n"); 
    } 
} 

/* Print_histo */ 

我想知道该程序是否在逻辑上错误?如果在这种情况下它在逻辑上是错误的,那么为什么它有时会显示直方图输出。谢谢!

+5

请使用调试器来缩小您的问题。 – Mat

+1

在进行高级编程(如多线程)之前,您需要学习C的基础知识。如果你从main()和向下读你的程序,你应该能够在几秒钟内找到bug。 – Lundin

如何之前 'P' 移动这一行

p=(struct1 *)malloc(sizeof(struct1)); 

用于分配的成员。

+0

谢谢!现在我没有看到分段错误(核心转储),而不是正确的输出:)我必须再次开始我的斗争:) – Deepak

+0

您可能想从一开始就仔细检查代码中的逻辑,并且确保它实际上做你想做的事情。一种方法是自己运行每个例程而不用线程来查看它是否正常工作,最后当你验证了正确性时,再把它们放在一起:) – DNT

+0

首先,我创建了串行直方图程序,然后当我看到正确性它..然后我开始与pthreads ..谢谢! – Deepak