I have a strange problem related to a while loop. I have a function which is called at the end of the parent of a process (print_file()
) and it doesn't accept a true condition to go ahead. This is my simple multiprocess code as you can see below.
#include /* basic I/O routines. */
#include
#include /* define fork(), etc. */
#include /* define pid_t, etc. */
#include /* define wait(), etc. */
#include /* define signal(), etc. */
#include
#include
#include
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 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 printf("%d", i);
i++;
j++;
if(i==10){
i=0;
}
}
return;
}
In the print_file
function it never enters into the while loop even when the condition is satisfied. But whenever I put a printf on the first line of the print_file
function to check if it does succesfully enter it prints. (Be carefull that counter
is a global variable). What causes this problem?
Answer
The output from the loop is not appearing due to stdout
being buffered (the printf()
statement inside the loop contains no \n
and stdout
is not explicitly fflush()
d) and the call to execl()
in main()
, which replaces the current process image and stdout
buffer is not flushed as usual on a normal program exit. Add a new-line character to the printf()
or explicitly call fflush(stdout);
after the loop.
There is a buffer overrun, causing undefined behaviour:
char* str = (char*)malloc(1);
allocates 1 byte, str
is then used thus:
fscanf(fptr,"%s%d",str,&temp);
fscanf()
adds a null terminator overruning the end of str
even if only one char
is read. I can't see a reason for dynamically allocating this or even when it needs to be an array as the format of the lines seems to be a single char
followed by an int
:
fprintf(fptr,"A %d\n",i);
To fix this problem, just use a char
and the format specifier %c
instead:
char ch;
if (2 == fscanf(fptr, "%c%d", &ch, &temp))
{
}
Always check return values (fopen()
, fprintf()
, fscanf()
etc).
No comments:
Post a Comment