Reputation: 469
I've made a very simple program calling forking and calling another problem.While it does what I want to , a bug occurs and cout occurs double the times of for loop. Here is the code : main.cpp
`#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
using namespace std;
char *Strduplicate(const char *source) {
char *dest = (char *) malloc(strlen(source) + 1); // +1 = '\0'
if (dest == NULL)
return NULL;
strcpy(dest, source);
return dest;
}
string Get_cwd(string word) {
char cwd[256];
getcwd(cwd, sizeof(cwd));
strcat(cwd,"/");
strcat(cwd,word.c_str());
string returnVal(cwd);
return returnVal;
}
void Call_exec(const char *name,int value) {
char *exec_array[3];
exec_array[0] = Strduplicate(name);
exec_array[1] = (char *)malloc(2);
exec_array[1] = (char *)"-m";
asprintf(&(exec_array[2]), "%d", value);
for (int i = 0 ; i < 3; i++)
cout << exec_array[i] << " ";
cout << endl;
execv(exec_array[0],exec_array);
}
int main(int argc ,char **argv) {
srand(time(NULL));
/* Getting arguments */
//........
/* Spawning children */
for (int i = 0 ; i < 3 ; i++ ) {
int value = rand()%100 + 1;
pid_t waiterpid = fork();
if (waiterpid < 0)
cout << "ERROR FORK" << endl;
else if (!waiterpid) {
string program_name = Get_cwd("child");
Call_exec(program_name.c_str(),value);
}
}
return EXIT_SUCCESS;
}
`
and the other process is child.cpp
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int main(int argc ,char **argv) {
cout << "Child #" << getpid() << " has started" << endl;
int value;
/* Getting arguments */
if (argc != 3) {
cerr << "ERROR : Wrong arguments" << endl;
exit(EXIT_FAILURE);
}
else {
if (strncmp(argv[1],"-m",2) == 0)
value = atoi(argv[2]);
}
cout << "Child has " << value << endl;
return EXIT_SUCCESS;
}
the output is
mypath/child -m 31
mypath/child -m 23
mypath/child -m 48
mypath/child -m 23
mypath/child -m 48
alex@alex$ Child #13063 has started
Child #13062 has started
Child has 48
Child has 23
mypath/child -m 48
Child #13064 has started
Child has 48
So what I misunderstand here?
Upvotes: 2
Views: 157
Reputation: 118292
What's misunderstood here are the general principles of writing modern C++ code. There is no reason whatsoever to use these awful-looking C-style dynamic memory allocations. Everything that's done here can be done much cleaner, using containers, with the resulting code being at least three times smaller.
Oh, and execv
's parameter array must be terminated by a NULL
pointer. It is not, so this results in undefined behavior. Most likely, the execv
system call fails, due to this garbage parameter - most likely with an EFAULT
according to my perusal of its manual page.
Thusly, execv()
actually returns in the child process. Since the shown code fails to check its return value: a child process, randomly, is going to continue executing upon returning from execv()
, returning to main()
in the child process, and continues with its own merry-go-round of the outer for
loop, hence resulting in the duplicate output.
Upvotes: 1