#include <stdio.h> #include <string.h> #include <pthread.h> pthread_mutex_t mtx; //переменная мьютекса typedef struct { char slovo[20]; char str[20]; int res; int col_words; } pthrData; void* process(void* thread_data) { pthrData* data = (pthrData*) thread_data; //создаем указатель на структуру pthread_mutex_lock(&mtx); printf("tread is work\n"); char* instr; double proc; data->col_words++; //количество слов instr = strstr(data->str, data->slovo); //ищем слово в строке if (instr != NULL) { data->res += strlen(data->slovo); //считаем символы } proc = (data->res + data->col_words - 1) * 100 / strlen( data->str); //вычисляем процент printf("%.2lf", proc); pthread_mutex_unlock(&mtx); usleep(50000); } void main(void) { pthread_mutex_init(&mtx, NULL); char S1[20], S2[20]; char sp[10] = " "; char* istr; int res = 0, col_w = 0, tmp, i = 0; double proc; printf("Enter S1, S2\n"); gets(S1); gets(S2); if (strlen(S1) <= strlen(S2)) { istr = strtok(S1, sp); while (istr != NULL) { col_w++; //считаем количество слов istr = strtok(NULL, sp); } printf("tre"); printf("%d", col_w); pthread_t* threads = (pthread_t*) malloc(col_w * sizeof( pthread_t)); //выделяем память под переменные потоков pthrData* threadData = (pthrData*) malloc(col_w * sizeof( pthrData)); //выделяем память под структуру, для отправки в функцию потока for (int i = 0; i < col_w; i++) { strncpy(threadData[i].slovo, istr, 20); strncpy(threadData[i].str, S2, 20); threadData[i].res = 0; threadData[i].col_words = 0; pthread_create(&(threads[i]), NULL, process, &threadData[i]); // создаем поток } for (int i = 0; i < col_w; i++) { pthread_join(threads[i], NULL); // блокируем потоки } free(threads); // чистим память free(threadData);// чистим память } return 0; } 

Comparison of strings of arbitrary content and output of percent similarity

Error - Segmentation fault. At the compilation stage it produces the following:

enter image description here

  • one
    That is, it is still going? - vp_arth
  • Don't you want to start compiling without warnings? Including all the necessary header files? - Harry
  • @vp_arth: This is not called "gathered," even if it is "all the same gathered." - AnT
  • one
    @ Vadim Moroz, please insert text with text , not a picture! - mymedia
  • one
    @vp_arth, with a million warnings from the compiler and even the linker. - 0andriy

2 answers 2

In addition to the answer already given.

  1. Your word counting loop ends with istr == NULL . Then, in the next cycle, you boldly continue to copy some line from istr . What do you mean?

  2. The code contains the use of the strncpy function for the purpose of so-called. "secure string copy". The strncpy function is not intended for this. However, if you already decided to use it in this role, then do not forget to add null termination manually

     strncpy(threadData[i].slovo, istr, 20); threadData[i].slovo[19] = '\0'; 

    Otherwise, if the source string is longer than 19 characters, your resulting string remains non-terminated. If this happens, then it is clear that the call to strstr in the stream will fall. (In your code, this will not happen, because everything will be covered on gets , but nonetheless.)

    On Linux, you also have at hand strlcpy designed specifically for safe copying of lines without additional crutches.

  3. After you have disassembled a line into words with the first pass using such a destructive method as strtok , in order to “scratch” these words from the disassembled line again, you have to make a number of [non-trivial] gestures. I do not see these gestures in your code.

    Maybe it was not worth using strtok ?

  4. The gets function is officially removed from the standard C and C ++ libraries. Forget about its existence.

  • 2. Even in the case of strlcpy() no one has canceled the need to check for errors. ;) - 0andriy
  • @ 0andriy: It’s not quite clear what kind of “mistakes” you are talking about. - AnT
  • On the obvious, you gave an example that the string can be longer than 19 bytes, one problem is non-terminating, which you described. The second, the actual circumcision. See what strlcpy() returns. And yet, this is still not a panacea, if you do not build a library with _FORTIFY_SOURCE. - 0andriy
  • @ 0andriy: Well, this is already a meta-question: does the overfill protection based on clipping the string suit the author? I can only guess about this. And _FORTIFY_SOURCE is a completely orthogonal theme. - AnT
  • 1. So that's it, in good code, we handle this error, in bad ... well, you see the bad code yourself. 2. Why? This is precisely in relation to the question of the appropriateness of using strlcpy() as such. Another thing is that now finding the libc compiled without this flag is probably hard. - 0andriy

Let's read the compiler messages together.

implicit declaration of function FOO

Header files for the declaration of the FOO function are not included. In your case, this is <stdlib.h> and <unistd.h> (which is needed for each function - see man FOO )

warning: 'return' with a value, in function returning void

The main() function is declared as returning nothing ( void ), and at the end is return 0 . Change the main() prototype to the correct one.

warning: the `gets' function is dangerous and should not be used.

Forget about this function, the answer to the next question was.

Now why the error can get out. If the function has no prototype, then the C compiler will assume that its prototype is int foo() . And build the code accordingly. Perhaps this is the cause of errors in the period of execution. Or maybe not :) But first, you need to deal with the descriptions of things and build the program without warning.

And for the future: for catching such errors in Linux, there are many effective tools, starting with the debugger, tracers, and ending with valgrind . You need to master them on a mandatory basis, and the sooner you start, the better. And here is just a good reason to start :)

  • Corrected all the above, the error did not disappear - Vadim Moroz
  • one
    Well, vaigrind / debugger in hand and forward :) Tip: with such input data does not fall: S1: "1 2 3", S2: "2" . And with such - falls: S1: "2", S2: "1 2 3" - PinkTux
  • @VadimMoroz, in fact, the moment of the fall and the reasons are clearly visible in the debugger, even before the threads are created. - PinkTux
  • @PinkTux, but there is also if (strlen(S1) <= strlen(S2)) course, in the first case, nothing will fall. =) - vp_arth
  • "If the function has no prototype, then the C compiler will assume that its prototype is int foo ()." - Is it? Should I deduce in accordance with the arguments passed? Or are you talking about the return type? - Qwertiy