Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用fork()计算收到的命令行参数的总和时出现问题_C_Unix_Fork - Fatal编程技术网

C 使用fork()计算收到的命令行参数的总和时出现问题

C 使用fork()计算收到的命令行参数的总和时出现问题,c,unix,fork,C,Unix,Fork,我试图根据从命令行收到的一组数字来计算总和,我使用一个名为worker的配套程序来完成计算。如果收到的数字量为奇数,它将在数字量上加一个零,使集合为偶数 这是一种可以理解的程序流程(归功于Alok): 举个例子可以更清楚地说明这一点: 假设您要添加7个数字:1234567 /协调员1234567 输入=[12345670] n=len(输入)=8 m=n/2=4 输出=[0] 我们分叉4个进程,第一个进程得到[12],第二个进程得到[34] 这4个进程分别返回3、7、11、7,我们将其分配给输出

我试图根据从命令行收到的一组数字来计算总和,我使用一个名为worker的配套程序来完成计算。如果收到的数字量为奇数,它将在数字量上加一个零,使集合为偶数

这是一种可以理解的程序流程(归功于Alok):

举个例子可以更清楚地说明这一点:

假设您要添加7个数字:1234567

/协调员1234567

  • 输入=[12345670]
  • n=len(输入)=8
  • m=n/2=4
  • 输出=[0]
  • 我们分叉4个进程,第一个进程得到[12],第二个进程得到[34]
  • 这4个进程分别返回3、7、11、7,我们将其分配给输出
  • 输出有4个元素,因此我们为新输入分配了4+1=5个元素的空间
  • 设置输入=[3 7 11 7 0]
  • n=len(输入)=5
  • m=n/2=2
  • 输出=[0]
  • 我们分叉两个进程,第一个得到[37],第二个得到[11]7
  • 这两个进程返回10,18,我们将其分配给输出
  • 输出有2个元素,因此我们为新输入分配2+1=3个元素的空间
  • 设置输入=[10 18 0]
  • n=len(输入)=3
  • m=n/2=1
  • 输出=[0]
  • 我们分叉一个进程,得到[10 18]
  • 进程返回28,我们将其分配给输出
  • 输出有1个元素,所以我们完成了 虽然在这组特殊的数字上,我得到:

    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 ***
    
    后面是堆错误列表

    我认为我没有正确地重新分配指针的大小,在第一次调用next_step()之后,我试图将旧输出重定向到新输入。因此,它试图将数据放入内存中没有空间的部分

    更新:

    @诺曼

    这是我收到的输出:

    ==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)
    

    如果要更改指针,请尝试此操作

    无效更改指针(int**输入,int**输出)


    变更指针(输入和输出)

    Ray,如果没有看到错误的更多细节,就很难知道出了什么问题。如果,正如我所怀疑的,这些都是运行时错误,您可以在下面运行代码吗
    valgrind
    在精确定位内存错误方面非常有效;使用您的应用程序,您将需要

    valgrind --trace-children=yes ./coordinator 1 2 3 4
    
    编辑:好的,通过valgrind错误,我们可以看到(a)您正在向
    printf
    传递一些不可靠的东西(如果您使用
    -g
    编译,您将获得准确的行号),并且您正在调用
    realloc
    ,但不是在
    malloc
    返回的指针上。也许你做过一些指针运算


    如果不看代码,就不能说更多,但我希望valgrind对您有所帮助。

    您有几个错误:

  • for(i=0;i
  • while(计算>0)

  • 您应该考虑编写一个函数,让我们将其称为
    step_once()
    ,它将使用
    n
    数字执行
    input
    ,并使用
    m=n/2
    元素写入相应的
    output
    <上面的code>n
    是输入数字的数目+1,
    input
    的最后一个元素等于0

    在驱动程序函数中,假设
    main()
    :如果
    output
    包含1个数字,则完成。否则,您将重新分配
    input
    以包含
    n_new=m+1
    元素,重新分配
    output
    以包含
    m_new=n_new/2
    元素,并再次调用函数
    step_()。你一直这样做直到你得到一个号码:

    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
    
    下一步功能(输入、输出、n、m): n:=输入数#大于1 #要求和的数字的数目 m:=n/2#C分部 n_儿童:=m i:=0 而我
    优点是,您可以测试
    next_step()
    函数,以确保它工作正常,从而使调试更容易

    举个例子可以更清楚地说明这一点:

    假设您要添加7个数字:1234567

  • 输入
    =[1 2 3 4 5 6 7 0]
  • n
    =len(
    input
    )=8
  • m
    =
    n/2
    =4
  • 输出
    =[0]
  • 我们分叉4个进程,第一个进程得到[12],第二个进程得到[34]
  • 这4个进程分别返回3、7、11、7,我们将其分配给
    输出
  • output
    有4个元素,因此我们为新的
    输入分配了4+1=5个元素的空间
  • 设置
    输入
    =[3 7 11 7 0]
  • n
    =len(
    input
    )=5
  • m
    =
    n/2
    =2
  • 输出
    =[0]
  • 我们分叉两个进程,第一个得到[37],第二个得到[11]7
  • 这两个进程返回10、18,我们将其分配给
    输出
  • 输出
    有2个元素,因此我们为新的
    输入
    分配了2+1=3个元素的空间
  • 设置
    输入
    =[10 18 0]
  • n
    =len(
    input
    )=3