저는 이것을 이해할 수 없습니다. 이 코드를 Code :: Blocks가있는 Windows 컴퓨터에서 컴파일하면 제대로 작동하지만 Cygwin 또는 실제 유닉스 컴퓨터에서 Make를 컴파일하려고하면 학교에서 이상한 동작이 발생합니다. translate()에 "client1.txt"를 전달합니다.strcat가 내 문자열을 덮어 씁니다.
void translate(char* filepath){
char output_filepath[181];
strcpy(output_filepath, filepath);
printf("%s\n", output_filepath); //this prints out "client1.txt" which is correct
char* ptr = strcat(output_filepath, ".translated");
printf("%s\n", output_filepath); //this prints out ".translated" which is wrong
printf("%s\n", ptr); //also prints out ".translated" wrong again
...more stuff...
}
이렇게하면 output_filepath에서 fgets를 사용하려고 할 때 세그먼트 화 오류가 발생합니다. 아무도 무슨 일이 일어나고 있는지 알고 있습니까? 더 설명해야합니까? Unix에서 컴파일 할 수 있어야합니다.
여기 전체 프로그램입니다. 너무 길지 않기를 바랍니다. 그것은 선생님이 우리에게 일하도록 주신 프로그램이지만 실행을 못하게합니다. 그것은 단지 나에게 세분화 오류를 제공하고 나는 위의 섹션을 추적했다. 당신이 기대하는대로
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
struct tparam{
int tid;
};
int NTHREADS = 5;
#define LOOPS 10000
int qfilled = 0;
int qin = 0;
int qout = 0;
char queue[3000][2][161];
char dic[7000][2][161];
int dic_size = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t flag_mutex = PTHREAD_MUTEX_INITIALIZER;
char * dummystatus[10];
char * lookup(char * word)
{
int i;
for(i = 0; i < dic_size; ++i)
{
if(strcmp(word, dic[i][0])==0)
return dic[i][1];
}
return word;
}
void translate(char filepath[])
{
char output_filepath[181];
strcpy(output_filepath, filepath);
strcat(output_filepath, ".translated");
FILE * client_file = fopen(filepath,"r");
FILE * translated_client_file = fopen(output_filepath,"w");
char line [161];
char * tmpPtr;
char * token;
while((tmpPtr=fgets(line, 160, client_file))!= NULL) {
if(strcmp(line,"\n") == 0 || line == NULL)
continue;
token = strtok_r(line, " \t\n", dummystatus);
while(token != NULL && strcmp(token,"\n") != 0){
fputs(lookup(token), translated_client_file);
fputs(" ", translated_client_file);
token = strtok_r(NULL, " \t\n", dummystatus);
}
fputs("\n", translated_client_file);
}
fclose(client_file);
}
void *do_work(void * p) {
struct tparam * param = (struct tparam *)p;
while(qfilled != 1);//wait for queue to be filled
int cindex;
while(1){
//check for more clients
pthread_mutex_lock(&mutex);
if(qout >= qin){
pthread_mutex_unlock(&mutex);
break;
}
//process client
cindex = qout;
printf("Thread %d is handling client %s\n",param->tid, queue[cindex][1]);
qout++;
pthread_mutex_unlock(&mutex);
char filepath[161];
if(queue[cindex][0][strlen(queue[cindex][0])-1] == '\n')
strncpy(filepath,queue[cindex][0],strlen(queue[cindex][0])-1);
else
strcpy(filepath,queue[cindex][0]);
translate(filepath);
printf("Thread %d finished handling client %s\n",param->tid, queue[cindex][1]);
//usleep(rand()%100000+10000);
}
pthread_exit(NULL);
}
void addDicEntry(char line[]){
char * first = strtok_r(line, " \t", dummystatus);
char * second = strtok_r(NULL, " \t", dummystatus);
char englishWord[161];
if(1==1 || second != NULL)
{
strcpy(dic[dic_size][0], first);
strncpy(englishWord, second, strlen(second)-1);
englishWord[strlen(second)-1] = '\0';
strcpy(dic[dic_size][1], englishWord);
dic_size++;
}
}
int main(int argc, char *argv[]) {
srand(time(NULL));
if(argc < 2){
printf("No dictionary file provided\n");
exit(1);
}
//read dictionary
int i;
for(i = 0; i < 10; ++i)
dummystatus[i] = (char*)malloc(10);
FILE * dic_file = fopen(argv[1],"r");
if(dic_file == NULL)
{
printf("Dictionary file does not exist\n");
exit(1);
}
char line [161];
char * tmpPtr;
while((tmpPtr=fgets(line, 160, dic_file))!= NULL) {
if(strcmp(line,"\n") == 0 || strcmp(line,"") == 0 || line == NULL)
break;
addDicEntry(line);
}
fclose(dic_file);
//End read dictionary
//Creating threads
if(argc >= 3)
NTHREADS = atoi(argv[2]);
pthread_t * threads = (pthread_t *)malloc(NTHREADS*sizeof(pthread_t));
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i=0; i<NTHREADS; i++) {
struct tparam * param = (struct tparam *)malloc(sizeof(struct tparam *)*1);
param->tid = i+1;
//printf("Thread %d is being created\n",param->tid);
pthread_create(&threads[i], &attr, &do_work, param);
}
//End creating threads
//insert clients in Q
FILE * clients_file = fopen("clients.in","r");
char cid_str[10];
while((tmpPtr=fgets(line, 160, clients_file))!= NULL) {
if(strcmp(line,"\n") == 0 || strcmp(line,"") == 0 || line == NULL)
break;
pthread_mutex_lock(&mutex);
strcpy(queue[qin][0],line);
sprintf(cid_str, "%d", qin+1);
strcpy(queue[qin][1],cid_str);
qin++;
pthread_mutex_unlock(&mutex);
}
fclose(clients_file);
//for (i=0; i<qin; i++)
//printf("%s\n", queue[i][0]);
qfilled = 1;
printf("Q Filled\n");
//End insert clients in Q
//printf("Waiting for Threads\n");
for (i=0; i<NTHREADS; i++)
pthread_join(threads[i], NULL);
//printf("Threads Finished\n");
pthread_attr_destroy(&attr);
pthread_exit(NULL);
}
여기 유닉스에서 gcc를 사용하여 테스트 했으므로 제대로 작동합니다. 어쩌면 컨텍스트/정보를 조금 더 제공 할 수 있습니까? –
그럼 바로 출력 해 봅시다. 출력은 "client1.txt \ n.translated \ n.translated"이지만 "client1.txt \ nclient1.txt.translated \ nclient1.txt.translated"여야합니까? 후자가 내가 얻는 것이다. 그것은 당신의 경우에'strcat' 대신에'strcpy'를 호출하는 것과 같은 종류의 소리입니다. – Edmund
나는'do_work' 함수에서 (지금 당장은 매우 유용한 설명 이름을 무시할 것입니다.) 여러분은'strncpy'를 제한된'strcpy'로 사용하고 있습니다. 실제로' t는 문자열을 nul-terminate하는 것이 보장되지 않기 때문이다. 이것은 약간의 귀찮은 코너 케이스를 만들 가능성이 있습니다. 아마 여기 버그는 아니지만, 아직 사용하지 않는 것이 좋습니다. –