C pthread总线错误

C pthread总线错误,c,pthreads,C,Pthreads,我在做运动。目标是用C语言编写一个破解DES加密密码的程序。 现在我有以下执行流程: 加载字典 查字典 暴力搜索前4个字符 字典搜索与暴力相结合(搜索 组合)。只有7-6个字符的字典单词 暴力搜索前5个字符 字典搜索与暴力相结合(搜索 组合)。只有5-4个字符的字典单词 暴力搜索最多8个字符 该程序运行良好,但我想通过使用多个 线程: 第一螺纹-主螺纹 第二个线程-字典和字典结合暴力 搜索 第三个线程-暴力搜索 我已经开始制作一个基本的字典搜索线程函数,但是 它因总线错误(MacOSX)而失败,

我在做运动。目标是用C语言编写一个破解DES加密密码的程序。 现在我有以下执行流程:

  • 加载字典
  • 查字典
  • 暴力搜索前4个字符
  • 字典搜索与暴力相结合(搜索 组合)。只有7-6个字符的字典单词
  • 暴力搜索前5个字符
  • 字典搜索与暴力相结合(搜索 组合)。只有5-4个字符的字典单词
  • 暴力搜索最多8个字符
  • 该程序运行良好,但我想通过使用多个 线程: 第一螺纹-主螺纹 第二个线程-字典和字典结合暴力 搜索 第三个线程-暴力搜索

    我已经开始制作一个基本的字典搜索线程函数,但是 它因总线错误(MacOSX)而失败,应该从这里开始读取单词 从字典文件。同样的代码在常规的非- 线程函数

    代码如下:

    #include <pthread.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    #define _XOPEN_SOURCE
    #define MAXLINE 40
    #define MAXPASS 9
    
    /* dictionary search thread function */
    void * dictionary(void * argv)
    {
        /* initializing SALT */
        char salt[3];               // defining salt (length is always 2 chars + "\0")
        strncpy(salt, argv, 2);     // copying the first 2 characters from encrypted password to salt
        salt[2] = '\0';             // placing null character to make salt a string
    
        /* defining and initializing password */
        char password[14];
        strcpy(password, argv);
        /* defining candidate */
        char  candidate[MAXPASS];
    
        /* opening file */
        FILE *fp;
        if ((fp = fopen("/usr/share/dict/words", "r")) == NULL)
        {
            printf("Error: Can not open file.\n");
            return (void *) -1;
        }
        printf("Open file: Ok\n");
        char line[MAXLINE];
        printf("Counting words: "); 
        /* counting words the file contains */
        int ctr = 0;    // words counter variable 
        int len;        // store length of the current line
        while (fgets(line, MAXLINE, fp) != NULL && line[0] != '\n')
        {
            if ((len = strlen(line)) <= MAXPASS && len >= 4)
                ctr++;  // will be real+1 when the loop ends
        }
        ctr--;          // adjusting to real words count
        rewind(fp);     // go back to the beginning of file
        printf("%d words\n", ctr);
    
        /* create an array of strings and fill it with the words from the dictionary */
        printf("Creating array for file contents: ");
        char words[ctr][MAXPASS];
        int i = 0;      // loop counter variable
        printf("Ok\n");
        /************************************* BUS ERROR *********************************************/
        printf("Reading file contents: ");
        while (fgets(line, MAXLINE, fp) != NULL && line[0] != '\n')
        {
            if ((len = strlen(line)) <= MAXPASS && len >= 4)
            {
                line[len-1] = '\0';
                strcpy(words[i], line);
                printf("%d: %s\n", i, words[i]);
                i++;
            }
        }
        printf("Ok\n");
        printf("Loaded %d words...\n", ctr);
    
        /* closing file */
        printf("Close file: ");
        if (fclose(fp) != 0)
        {
            fprintf(stderr, "Error: Can not close file\n");
            return (void *) -2;
        }
        printf("Ok\n");
    
        /* starting search dictionary search */
        printf("Starting Dictionary Search...\n");
        int match = 0;
        char * encrypted;
        int n;
        for (i = 0; i <= ctr && !match; i++)
        {
            encrypted = crypt(words[i], salt);
            if ((strcmp(encrypted, password)) == 0)             // if candidate == password
            {
                match = 1;
                strcpy(candidate, words[i]);
                printf("Password: %s\n", candidate);
                return (void *) 1;
            }
        }
    
        return (void *) 0;
    }
    int main(int argc, char * argv[])
    {
        /* if there are less/more than 1 argument, notify the user and exit with an error code  1 */
        if (argc != 2)      // first argument is always the name of the program
        {
            printf("Error 1: Wrong number of arguments\n");             
            return 1;
        }
        /* if the length of the argument is less/more than 13 characters, notify the user and exit with an error code 2 */
        int length = strlen(argv[1]);
        if (length != 13)
        {
            printf("Error 2: The length of an encrypted password should be 13 characters\n");
            return 2;
        }
    
        pthread_t dct;      // dictionary thread identifier
        void *status;       // thread return value
    
        /* creating dictionary thread */
        pthread_create(&dct,NULL,dictionary,argv[1]);
    
        printf("Waiting for thread to terminate...\n");
        pthread_join(dct,&status);
    
        //printf("Return Value: %d\n",(int)status);
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #定义_XOPEN_源
    #定义MAXLINE 40
    #定义maxpass9
    /*字典搜索线程函数*/
    void*字典(void*argv)
    {
    /*初始化盐*/
    char salt[3];//定义salt(长度始终为2个字符+“\0”)
    strncpy(salt,argv,2);//将前2个字符从加密密码复制到salt
    salt[2]='\0';//放置空字符以使salt成为字符串
    /*定义和初始化密码*/
    字符密码[14];
    strcpy(密码,argv);
    /*确定候选人*/
    字符候选[MAXPASS];
    /*打开文件*/
    文件*fp;
    if((fp=fopen(“/usr/share/dict/words”,“r”))==NULL)
    {
    printf(“错误:无法打开文件。\n”);
    返回(无效*)-1;
    }
    printf(“打开文件:Ok\n”);
    字符行[MAXLINE];
    printf(“计算字数:”);
    /*计算文件包含的字数*/
    int ctr=0;//字计数器变量
    int len;//存储当前行的长度
    while(fgets(line,MAXLINE,fp)!=NULL&&line[0]!='\n')
    {
    如果((len=strlen(line))=4)
    ctr++;//循环结束时将为实+1
    }
    ctr--;//调整到实词计数
    倒带(fp);//返回文件的开头
    printf(“%d字\n”,ctr);
    /*创建一个字符串数组,并用字典中的单词填充它*/
    printf(“为文件内容创建数组:”);
    字符字[ctr][MAXPASS];
    int i=0;//循环计数器变量
    printf(“Ok\n”);
    /*************************************总线错误*********************************************/
    printf(“读取文件内容:”);
    while(fgets(line,MAXLINE,fp)!=NULL&&line[0]!='\n')
    {
    如果((len=strlen(line))=4)
    {
    第[len-1]行=“\0”;
    strcpy(字[i],行);
    printf(“%d:%s\n”,i,单词[i]);
    i++;
    }
    }
    printf(“Ok\n”);
    printf(“加载了%d个单词…\n”,ctr);
    /*关闭文件*/
    printf(“关闭文件:”);
    如果(fclose(fp)!=0)
    {
    fprintf(stderr,“错误:无法关闭文件\n”);
    返回(无效*)-2;
    }
    printf(“Ok\n”);
    /*正在启动搜索词典搜索*/
    printf(“开始字典搜索…\n”);
    int匹配=0;
    字符*加密;
    int n;
    对于(i=0;i我猜这是你的问题:

    char words[ctr][MAXPASS];
    

    当你运行一个单线程程序时,你有足够的地址空间让堆栈向下生长,库和程序可执行空间长大,堆在中间。

    但是,当您运行多线程程序时,每个线程都有自己的堆栈,如果线程可用的堆栈空间明显小于字典大小,我也不会感到惊讶。(有关每线程堆栈默认大小的详细信息,请参阅系统上的
    pthread\u attr\u getstack()
    manpage。)

    使用
    malloc(3)
    分配该数组,并查看您的程序是否更进一步

    您必须使用另一个函数,因为您无法为数组赋值,但当您编写一个应作为参数传递数组的函数时,它实际上会衰减到函数调用中强制转换的指针:
    char(*)[WORDLEN]
    (可能已编写:
    void fun(char(*)[WORDLEN])
    也一样,但我认为这不太清晰。)


    我总是有点担心,当我用cast使警告静音时,就像我在这里所做的那样,但这确实执行了一个大的分配,而不是数千个小的分配,这可能会造成巨大的性能差异。(测试两者并查看。)

    请将您的代码粘贴在此处,而不是其他网站上。此处是高质量问题和答案的存储库;当您的代码宿主关闭其门或过期旧帖子时会发生什么情况?这将成为(更多)无用,对将来的其他人没有帮助。谢谢!很抱歉在pastebin上发布代码,但我是stackoverflow新手,在格式化代码时遇到问题…格式化代码很简单。您只需将一行缩进4个空格,或者选择整个块并单击
    {}编辑器工具栏中的
    按钮。我与手工设置代码格式斗争了太长时间,才发现
    {}
    按钮就在眼前我知道我过去忽略了HTML编辑器小部件上的按钮,但这一个很有用。:)我知道如何分配2d数组的int,但是我在使用char时遇到了麻烦。我尝试这样做,但仍然失败:char*words[ctr];inti;for(I=0;Ichar *words; words = malloc(ctr * sizeof(char)); int i; // loop counter variable for (i = ; i < ctr; i++) words[i] = malloc(MAXPASS * sizeof(char));
    $ cat multidimensional.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define NWORDS 1000
    #define WORDLEN 10
    
    void fun(char words[NWORDS][WORDLEN]) {
        int i, j;
        for (i=0; i<NWORDS; i++) {
            strcpy(words[i], "test");
        }
    
        for (i=0; i<NWORDS; i++) {
            printf("%s\n", words[i]);
        }
        return;
    }
    
    
    int main(int argc, char* argv[]) {
        char *w = malloc(NWORDS * WORDLEN * sizeof(char));
        memset(w, 0, NWORDS * WORDLEN * sizeof(char));
        fun((char (*)[WORDLEN]) w);
    
        return 0;
    }