我有一个与while循环相关的奇怪问题。我有一个函数,它在进程的父级(print_file()
)结束时调用,它不接受真正的条件继续。这是我的简单多进程代码,如下所示。
#include <stdio.h> /* basic I/O routines. */
#include <stdlib.h>
#include <unistd.h> /* define fork(), etc. */
#include <sys/types.h> /* define pid_t, etc. */
#include <sys/wait.h> /* define wait(), etc. */
#include <signal.h> /* define signal(), etc. */
#include <pthread.h>
#include <time.h>
#include <ctype.h>
void print_file(char* [], char* []);
void child_process(int,int);
void parent_process();
int counter=0;
int main(int argc, char* argv[]) {
counter = atoi(argv[1]);
int i,k;
pid_t child_pid;
int child_status;
char* array[counter];
srand ( time(NULL) );
int temp;
for(i=0; i<counter; i++){
temp = rand()%4;
child_pid = fork();
switch(child_pid) {
case -1:
printf("Error occured with fork()\n");
exit(1);
case 0:
child_process(i,temp); /* Child Process */
exit(0);
}
}
wait(&child_status);
parent_process();
execl("/usr/bin/killall","killall","tail",(char *) 0);
return 0;
}
void child_process(int i,int temp){
FILE* fptr;
fptr = fopen("sample.txt","a+");
if( temp==0 ) {
fprintf(fptr,"A %d\n",i);
}
else if( temp==1 ) {
fprintf(fptr,"C %d\n",i);
}
else if( temp==2 ) {
fprintf(fptr,"G %d\n",i);
}
else if( temp==3 ) {
fprintf(fptr,"T %d\n",i);
}
fflush(fptr);
sleep(1);
fclose(fptr);
}
void parent_process(void){
FILE* fptr;
fptr = fopen("sample.txt","r");
char* str = (char*)malloc(1);
int temp,i,k;
char* array_opst[counter];
char* array[counter];
i=0;
while(!feof(fptr)){
fscanf(fptr,"%s%d",str,&temp);
if(feof(fptr))
break;
if(strcmp(str,"A")==0){
array[temp]="A";
array_opst[temp]="T";
printf("Array[%d] = %s\n",temp,array[temp]);
}
else if(strcmp(str,"C")==0){
array[temp]="C";
array_opst[temp]="G";
printf("Array[%d] = %s\n",temp,array[temp]);
}
else if(strcmp(str,"G")==0){
array[temp]="G";
array_opst[temp]="C";
printf("Array[%d] = %s\n",temp,array[temp]);
}
else if(strcmp(str,"T")==0){
array[temp]="T";
array_opst[temp]="A";
printf("Array[%d] = %s\n",temp,array[temp]);
}
i++;
}
fclose(fptr);
free(str);
print_file(array,array_opst);
}
void print_file(char* array[counter], char* array_opst[counter]) {
int j=0,i=1;
while(j<counter){
printf("%d", i);
i++;
j++;
if(i==10){
i=0;
}
}
return;
}
在print_file
函数中,即使条件满足,它也永远不会进入while循环。但每当我在print_file
函数的第一行放置printf以检查它是否成功输入它打印。 (注意counter
是一个全局变量)。是什么导致这个问题?
答案 0 :(得分:5)
由于stdout
被缓冲,循环的输出没有出现(循环内的printf()
语句不包含\n
而stdout
未明确{{1} d)和fflush()
中execl()
的调用,它取代了当前的过程映像,并且main()
缓冲区在正常程序退出时不像往常一样被刷新。在stdout
添加换行符或在循环后显式调用printf()
。
存在缓冲区溢出,导致未定义的行为:
fflush(stdout);
分配1个字节,然后使用char* str = (char*)malloc(1);
:
str
即使只读取了一个fscanf(fptr,"%s%d",str,&temp);
, fscanf()
也会添加一个空终结符,超出str
的结尾。我无法看到动态分配它的原因,甚至当它需要是一个数组时,因为行的格式似乎是单个char
后面跟char
:
int
要解决此问题,请改为使用fprintf(fptr,"A %d\n",i);
和格式说明符char
:
%c
始终检查返回值(char ch;
if (2 == fscanf(fptr, "%c%d", &ch, &temp))
{
}
,fopen()
,fprintf()
等)。