因此,我尝试通过某个给定目录进行递归迭代,并将每个子目录中每个文件的所有内容复制到一个输出文件。我需要创建一个新线程来复制文件以及迭代任何子目录。我要做的是遍历终端给出的目录。每次调用iterate_dir时,都会创建一个pthreads数组并为其创建一个计数器,因此我可以在所有创建的线程加入后关闭目录。因此,如果找到了子目录,我将创建一个pthread来调用iterate_dir并将其传递给新路径,将pthread数组增加一个并将其存储在其中。如果找到了文件,我将创建一个pthread来调用copy_file,该文件将打开文件以读取其内容,并将每个字符存储到一个共享字符串中(该字符串是互斥的,并且大小是动态的)。但是,我不断遇到一些无法解释的细分错误。我输入了一个包含2个文件和2个子目录的目录,其中1个子目录为空,另一个包含1个文件。我尝试删除copy_file并使用它来调用它的pthread,但是我仍然遇到了段错误。我尝试删除我创建的pthread数组,但仍然存在段错误。我尝试使用gdb逐步解决它,但没有最终答案。我将提供两种情况,一种不带copy_file和pthread数组,一种不带。他们都存在段错误。我的问题是,即使没有分配任何东西,pthread segfault也会如何(就像没有copy_file和pthread数组的代码一样)?我真的很困惑,想知道是否有人对其他代码有任何想法甚至建议。谢谢。
没有pthread数组和copy_file(易于阅读)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <pthread.h>
#include <fcntl.h>
void* iterate_dir(void* args);
int main(int argc, char** argv){
char current_path[strlen(argv[1])+1];
strcpy(current_path,argv[1]);
pthread_t start;
pthread_create(&start,NULL,&iterate_dir,current_path);
pthread_join(start,NULL);
}
void* iterate_dir(void *args){
DIR *dd = opendir((char*)args);
struct dirent *curr;
while((curr = readdir(dd))!=NULL){
if(curr->d_type==DT_DIR && (strcmp(curr->d_name,".")==0 || strcmp(curr->d_name,"..")==0)){
continue;
}
if(curr->d_type==DT_DIR){
char new_path[strlen(curr->d_name)+strlen((char*)args)+2];
sprintf(new_path,"%s/%s",(char*)args,curr->d_name);
pthread_t new_thread;
pthread_create(&new_thread,NULL,&iterate_dir,new_path);
}else{
}
}
return NULL;
}
使用copy_file和pthread数组(要读取的内容)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <pthread.h>
#include <fcntl.h>
void* iterate_dir(void* args);
void* copy_file(void* args);
pthread_mutex_t mut_for_final_string;
pthread_mutex_t mut_for_current_string_position;
char* final_string;
int current_string_position;
int main(int argc, char** argv){
char current_path[strlen(argv[1])+1];
strcpy(current_path,argv[1]);
char new_file_path[strlen(argv[2])+15+1];
sprintf(new_file_path,"%s/%s",argv[2],"AllFiles-sorted");
int output = open(new_file_path, O_WRONLY|O_CREAT, 0666);
final_string = (char*)malloc(sizeof(char));
current_string_position = 0;
pthread_mutex_init(&mut_for_final_string,NULL);
pthread_mutex_init(&mut_for_current_string_position,NULL);
pthread_t start;
pthread_create(&start,NULL,&iterate_dir,current_path);
pthread_join(start,NULL);
write(output,final_string,current_string_position);
pthread_mutex_destroy(&mut_for_final_string);
pthread_mutex_destroy(&mut_for_current_string_position);
}
void* copy_file(void *args){
int input = open((char*)args,O_RDONLY);
char c;
while(read(input,&c,1)>0){
pthread_mutex_lock(&mut_for_final_string);
pthread_mutex_lock(&mut_for_current_string_position);
final_string[current_string_position] = c;
char* tmp = NULL;
tmp = realloc(final_string,(current_string_position)+2);
while(tmp==NULL){}
final_string = tmp;
(current_string_position)++;
pthread_mutex_unlock(&mut_for_current_string_position);
pthread_mutex_unlock(&mut_for_final_string);
}
close(input);
return NULL;
}
void* iterate_dir(void *args){
DIR *dd = opendir((char*)args);
struct dirent *curr;
pthread_t* tids = (pthread_t*)malloc(sizeof(pthread_t));
int tids_counter = 0;
while((curr = readdir(dd))!=NULL){
if(curr->d_type==DT_DIR && (strcmp(curr->d_name,".")==0 || strcmp(curr->d_name,"..")==0)){
continue;
}
if(curr->d_type==DT_DIR){
char new_path[strlen(curr->d_name)+strlen((char*)args)+2];
sprintf(new_path,"%s/%s",(char*)args,curr->d_name);
pthread_t new_thread;
pthread_create(&new_thread,NULL,&iterate_dir,new_path);
tids[tids_counter] = new_thread;
tids_counter++;
pthread_t* tmp_ptr = NULL;
tmp_ptr = realloc(tids, (sizeof(pthread_t)*(tids_counter+1)));
while(tmp_ptr==NULL){}
tids = tmp_ptr;
}else{
char old_path[strlen(curr->d_name)+strlen((char*)args)+2];
sprintf(old_path,"%s/%s",(char*)args,curr->d_name);
pthread_t new_thread;
pthread_create(&new_thread,NULL,©_file,old_path);
tids[tids_counter] = new_thread;
tids_counter++;
pthread_t* tmp_ptr = NULL;
tmp_ptr = realloc(tids, (sizeof(pthread_t)*(tids_counter+1)));
while(tmp_ptr==NULL){}
tids = tmp_ptr;
}
}
int i;
for(i=0;i<tids_counter;i++){
pthread_join(tids[i],NULL);
}
closedir(dd);
return NULL;
}
最佳答案
char new_path[strlen(curr->d_name)+strlen((char*)args)+2];
一旦离开声明的作用域,该内存地址即为无效,但您将该地址传递给了新的pthread。
关于c - pthread如何导致c中的段错误(尽管未分配内存)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53196590/