Этот код:
for (i = 0; i < nthreads; i++){
struct ft data[nthreads];
объявляет data
, который является действующим (разрешенным к использованию) в течение этого времени для l oop. Этот код:
pthread_create(&threads[i], &attr, (void*) countFrequency, (void*) &data[i]);
}
передает адрес data
в потоки и затем выходит из l oop. Как только l oop завершено, data
больше не является активным, и любой доступ к нему ведет к неопределенному поведению.
Компилятор может свободно записывать что-либо еще в память, где data
используется для be.
Непосредственная причина cra sh заключается в том, что если один из потоков не выполнит fopen
до того, как data
будет перезаписан, то fopen
может завершиться ошибкой и вы не проверяете ошибку в fopen
.
PS
Как отметил Эраклон, этот код: chunkSize = sizeof(argv[1])/nthreads;
будет делить sizeof(char*)
(4 или 8 в зависимости от будь то сборка для 32-битной или для 64-битной) по количеству потоков. Это вряд ли то, что вы хотите, и даст chinkSize==0
для nthreads > 4
на 32-битных и nthreads > 8
на 64-битных машинах.
PPS
В вашей программе также есть ошибка параллелизма: поскольку каждый из вызовов countFrequency
блокирует одни и те же lock
на все время , они все будут работать в последовательности (один за другим), а не параллельно. Таким образом, ваша программа будет работать медленнее, чем если бы вы просто выполняли всю работу в основном потоке.