Problem using fork () to calculate the total amount of command line arguments accepted

I am trying to calculate the sum based on sets of numbers obtained from the command line, and I am using a companion program called worker, due to the calculation for me. If the number of numbers received is odd, it will add zero to the number of numbers to make the set even.

This is the program flow in an understandable way (loan to Aloku):

An example will make this clear:

Let's say you want to add 7 numbers: 1 2 3 4 5 6 7

./ coordinator 1 2 3 4 5 6 7

  • input = [1 2 3 4 5 6 7 0]
  • n = len (input) = 8
  • m = n / 2 = 4
  • output = [0 0 0 0]
  • The fork 4 process, the first process receives [1 2], the second - [3 4], ...
  • 4 processes return 3, 7, 11, 7, respectively, which we assign for output.
  • output has 4 elements, so we allocate space for 4 + 1 = 5 elements for new input.
  • set input = [3 7 11 7 0]
  • n = len (input) = 5
  • m = n / 2 = 2
  • output = [0 0]
  • We start process 2, first we get [3 7], the second receives [11 7]
  • 2 processes return 10, 18, which we assign for output.
  • output has 2 elements, so we allocate space for 2 + 1 = 3 elements for new input.
  • set input = [10 18 0]
  • n = len (input) = 3
  • m = n / 2 = 1
  • output = [0]
  • We are casting one process that gets [10 18]
  • The process returns 28, which we assign for output.
  • the output has 1 element, so we are done.

Although on this particular set of numbers I get:

Process ID: 15195 Sum of 1 and 2 is 3 Process ID: 15196 Sum of 3 and 4 is 7 Process ID: 15197 Sum of 5 and 6 is 11 Process ID: 15198 Sum of 7 and 0 is 7 *** glibc detected *** ./coordinator: free(): invalid next size (fast): 0x080ec048 *** 

The following is a list of heap errors.

I believe that I am not redistributing the size of the pointers correctly, in which I am trying to redirect the old output to a new input after the first call to next_step (). Therefore, he is trying to put data in a piece of memory for which there is no space.

UPDATE:

@Norman

This is the result I get:

 ==3585== Memcheck, a memory error detector ==3585== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==3585== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==3585== Command: ./coordinator 1 2 3 4 ==3585== calc: 2: input[0]: 1 input[1]: 2 input[2]: 3 input[3]: 4 ==3585== Use of uninitialised value of size 4 ==3585== at 0x4076186: ??? (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x4079A81: vfprintf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x4080F7F: printf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x8048833: main (in /home/bryan/cpp/coordinator) ==3585== ==3585== Conditional jump or move depends on uninitialised value(s) ==3585== at 0x407618E: ??? (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x4079A81: vfprintf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x4080F7F: printf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x8048833: main (in /home/bryan/cpp/coordinator) ==3585== ==3585== Conditional jump or move depends on uninitialised value(s) ==3585== at 0x4077877: vfprintf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x4080F7F: printf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x8048833: main (in /home/bryan/cpp/coordinator) ==3585== ==3585== Conditional jump or move depends on uninitialised value(s) ==3585== at 0x407789B: vfprintf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x4080F7F: printf (in /lib/tls/i686/cmov/libc-2.10.1.so) ==3585== by 0x8048833: main (in /home/bryan/cpp/coordinator) ==3585== input[4]: 0 ==3586== Memcheck, a memory error detector ==3586== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==3586== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==3586== Command: ./worker 1 2 ==3586== Process ID: 3586 Sum of 1 and 2 is 3 ==3586== ==3586== HEAP SUMMARY: ==3586== in use at exit: 0 bytes in 0 blocks ==3586== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3586== ==3586== All heap blocks were freed -- no leaks are possible ==3586== ==3586== For counts of detected and suppressed errors, rerun with: -v ==3586== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6) ==3587== Memcheck, a memory error detector ==3587== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==3587== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==3587== Command: ./worker 3 4 ==3587== Process ID: 3587 Sum of 3 and 4 is 7 ==3587== ==3587== HEAP SUMMARY: ==3587== in use at exit: 0 bytes in 0 blocks ==3587== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3587== ==3587== All heap blocks were freed -- no leaks are possible ==3587== ==3587== For counts of detected and suppressed errors, rerun with: -v ==3587== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6) ==3585== Invalid write of size 4 ==3585== at 0x8048A3A: main (in /home/bryan/cpp/coordinator) ==3585== Address 0x417f0b4 is 8 bytes after a block of size 4 alloc'd ==3585== at 0x4024C6C: malloc (vg_replace_malloc.c:195) ==3585== by 0x4024CF6: realloc (vg_replace_malloc.c:476) ==3585== by 0x8048A25: main (in /home/bryan/cpp/coordinator) ==3585== ==3588== Memcheck, a memory error detector ==3588== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==3588== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==3588== Command: ./worker 3 7 ==3588== Process ID: 3588 Sum of 3 and 7 is 10 ==3588== ==3588== HEAP SUMMARY: ==3588== in use at exit: 0 bytes in 0 blocks ==3588== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3588== ==3588== All heap blocks were freed -- no leaks are possible ==3588== ==3588== For counts of detected and suppressed errors, rerun with: -v ==3588== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6) ==3585== Invalid read of size 4 ==3585== at 0x8048AB5: main (in /home/bryan/cpp/coordinator) ==3585== Address 0x417f0e0 is 0 bytes after a block of size 0 alloc'd ==3585== at 0x4024C6C: malloc (vg_replace_malloc.c:195) ==3585== by 0x4024CF6: realloc (vg_replace_malloc.c:476) ==3585== by 0x8048A77: main (in /home/bryan/cpp/coordinator) ==3585== The final sum is: 0==3585== ==3585== HEAP SUMMARY: ==3585== in use at exit: 28 bytes in 2 blocks ==3585== total heap usage: 4 allocs, 2 frees, 32 bytes allocated ==3585== ==3585== LEAK SUMMARY: ==3585== definitely lost: 8 bytes in 1 blocks ==3585== indirectly lost: 0 bytes in 0 blocks ==3585== possibly lost: 20 bytes in 1 blocks ==3585== still reachable: 0 bytes in 0 blocks ==3585== suppressed: 0 bytes in 0 blocks ==3585== Rerun with --leak-check=full to see details of leaked memory ==3585== ==3585== For counts of detected and suppressed errors, rerun with: -v ==3585== Use --track-origins=yes to see where uninitialised values come from ==3585== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 11 from 6) 
+4
source share
4 answers

You should consider writing a function, call step_once() , which will take input with numbers n and write the corresponding output elements with m = n/2 . n above is the number of input numbers + 1, and the last element of input is 0.

In your driver function, let's say main() : if output contains 1 number, you're done. Otherwise, you redistribute input to contain the elements n_new = m+1 , redistribute output to contain the elements m_new = n_new/2 , and call the step_once() function step_once() . You keep doing this until you get one number:

 function next_step(input, output, n, m): n := number of input numbers # this is 1 greater than # the number of numbers being summed m := n / 2 # C division n_children := m i := 0 while i < m: fork worker with input[2*i] and input[2*i+1] get result in output[i] i := i + 1 function main: set n := length(input) + 1 set m := n/2 allocate memory for input # n+1 elements, last = 0 allocate memory for output # m elements set values in input while True: next_step(input, output, n, m) if length or output == 1: done, return else: set n := length(output) + 1 set m := n/2 allocate space for new_input # n elements set new_input := output + [0] free input and output set input := new_input allocate memory for output # m elements 

The advantage is that you can test your next_step() function to make sure it works and thus makes debugging easier.

An example will make this clear:

Let's say you want to add 7 numbers: 1 2 3 4 5 6 7

  • input = [1 2 3 4 5 6 7 0]
  • n = len ( input ) = 8
  • m = n/2 = 4
  • output = [0 0 0 0]
  • The fork 4 process, the first process receives [1 2], the second - [3 4], ...
  • 4 processes return 3, 7, 11, 7, respectively, which we assign to output .
  • output has 4 elements, so we allocate space for 4 + 1 = 5 elements for the new input .
  • set input = [3 7 11 7 0]
  • n = len ( input ) = 5
  • m = n/2 = 2
  • output = [0 0]
  • We start process 2, first we get [3 7], the second receives [11 7]
  • 2 processes return 10, 18, which we assign to output .
  • output has 2 elements, so we allocate space for 2 + 1 = 3 elements for the new input .
  • set input = [10 18 0]
  • n = len ( input ) = 3
  • m = n/2 = 1
  • output = [0]
  • We are casting one process that gets [10 18]
  • The process returns 28, which we assign to output .
  • the output has 1 element, so we are done.
+1
source

Try it if you want to change pointers.

void ChangePointers (input int **, output int **)

and

ChangePointers (& input, & output);

0
source
Ray, it's hard to see what is wrong without seeing more details about the errors. If, as I suspect, these are runtime errors, can you run the code under valgrind ? valgrind extremely effective in detecting memory errors; with your application you need
 valgrind --trace-children=yes ./coordinator 1 2 3 4 

EDIT : OK, with valgrind errors, we can see that (a) you are passing something tricky to printf (if you compile -g you will get the exact line number), and also you call realloc , but not the pointer you received from malloc . Perhaps you did some pointer arithmetic?

I can't say more without seeing the code, but I hope you find valgrind useful.

0
source

You have several "one by one" errors:

  • for(i = 0; i < argc; i++)
  • while(calc > 0)
0
source

Source: https://habr.com/ru/post/1300516/


All Articles