首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用fork()计算接收到的命令行参数的总和时出错

使用fork()计算接收到的命令行参数的总和时出错
EN

Stack Overflow用户
提问于 2010-02-06 20:30:17
回答 4查看 1.4K关注 0票数 4

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

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

一个例子将使这一点更加明确:

假设您想要添加7个数字:1 2 3 4 5 6 7

1 2 3 4 5 6 7

  1. input =1 2 3 4 5 6 7 0
  2. n = len(input) =8
  3. m = n/2 =4
  4. output =0 0 0
  5. 我们叉4进程,第一进程得到1 2,第二进程得到3 4,…<代码>H 210<代码>H 1114个进程返回3,7,11,7,7。
  6. 输出有4个元素,因此我们为新输入分配4+1 =5个元素的空间。
  7. set input =3 7 11 7 0
  8. n = len(input) =5
  9. m = n/2 =2
  10. output =0

H 123我们分叉2个进程,首先得到3 7,第2得到11 7<代码>H 224>H 1252个进程返回10,18,这是我们分配给输出的。

  1. 输出有2个元素,因此我们为新输入分配2+1 =3个元素的空间。
  2. set input = 10 18 0
  3. n = len(input) =3
  4. m = n/2 =1
  5. output =

H 137我们叉一个进程,得到10 18 <>H 238>H 139进程返回28,分配给输出。

  1. 输出有一个元素,所以我们完成了。

尽管在这组特定的数字中,我得到了:

代码语言:javascript
复制
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()之后,我试图将旧的输出重定向到新的输入。因此,它试图将数据放入内存中没有空间的部分。

更新:

@诺曼

这是我收到的输出:

代码语言:javascript
复制
==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)
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-02-06 22:00:16

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

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

代码语言:javascript
复制
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

其优点是可以测试next_step()函数以确保其工作正常,从而使调试更容易。

一个例子将使这一点更加明确:

假设您想要添加7个数字:1 2 3 4 5 6 7

  1. input =1 2 3 4 5 6 7 0
  2. n = len(input) = 8
  3. m = n/2 = 4
  4. output =0 0 0
  5. 因此,我们为新的input.
  6. set input =3 7 11 7 0
  7. n = len(input) = n/2 = 2
  8. output =0
  9. 为4+1 =5元素分配了空间--我们分叉了2个进程,第一个是37个,第二个是117个
  10. ,两个进程返回10,18个,指定给output.
  11. output有2个元素,因此,我们为新的input.
  12. set input =1018 0
  13. n = len(input) = 3
  14. m = n/2 = 1
  15. output =
  16. 分配2+1 =3元素的空间。我们叉一个进程,得到1018
  17. ,进程返回28,分配给output.
  18. output有1个元素,所以就完成了。
票数 1
EN

Stack Overflow用户

发布于 2010-02-06 20:41:24

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

空ChangePointers(int **输入,int **输出)

ChangePointers(&input &output);

票数 0
EN

Stack Overflow用户

发布于 2010-02-06 20:55:41

雷,如果不看到更多关于错误的细节,就很难知道出了什么问题。如果如我所怀疑的那样,这些都是运行时错误,那么您能在valgrind下运行代码吗?valgrind在定位内存错误方面非常有效;在您的应用程序中,您需要

代码语言:javascript
复制
valgrind --trace-children=yes ./coordinator 1 2 3 4

编辑:好的,我们可以看到(a)将一些错误传递给printf (如果使用-g编译,您将得到确切的行号),并且调用realloc,而不是在从malloc返回的指针上调用realloc。也许你做过一些指针运算?

在没有看到代码的情况下,我不能说更多的话,但我希望您能找到更有帮助的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2214604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档