我正在尝试根据从命令行收到的数字组计算总和,我使用一个名为worker的配套程序来计算我。如果收到的数字是奇数,它会在数字量上加零,以使设定均匀。
这是一个可以理解的方式的流程(信用Alok):
一个例子可以说明这一点:
假设您要添加7个数字:1 2 3 4 5 6 7
./ coordinator 1 2 3 4 5 6 7
虽然在这个特定的数字集上我得到了:
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()之后我尝试将旧输出重定向到新输入。所以它试图将数据放入没有空间的内存部分。
更新
@Norman
这是我收到的输出:
==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)
答案 0 :(得分:1)
您应该考虑编写一个函数,让我们称之为step_once()
,input
将n
个output
,并用{{1}写入相应的m = n/2
元素。上面的n
是输入数字+ 1,最后一个元素input
等于0.
在你的驱动程序功能中,我们说main()
:如果output
包含1个数字,那么就完成了。否则,您需要重新分配input
以包含n_new = m+1
元素,重新分配output
以包含m_new = n_new/2
元素,然后再次调用函数step_once()
。你一直这样做,直到得到一个数字:
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
input
= [1 2 3 4 5 6 7 0] n
= len(input
)= 8 m
= n/2
= 4 output
= [0 0 0 0] output
。output
有4个元素,因此我们为新input
分配4 + 1 = 5个元素的空间。input
= [3 7 11 7 0] n
= len(input
)= 5 m
= n/2
= 2 output
= [0 0] output
。output
有2个元素,因此我们为新的input
分配2 + 1 = 3个元素的空间。input
= [10 18 0] n
= len(input
)= 3 m
= n/2
= 1 output
= [0] output
。答案 1 :(得分:0)
如果你想改变指针,试试这个。
void ChangePointers(int ** input,int ** output)
和
ChangePointers(&amp; input,&amp; output);
答案 2 :(得分:0)
Ray,如果没有看到有关错误的更多详细信息,很难知道出了什么问题。如果我怀疑这些是运行时错误,您可以在valgrind
下运行代码吗? valgrind
在查明内存错误方面非常有效;与您的应用程序,你会想要
valgrind --trace-children=yes ./coordinator 1 2 3 4
编辑:好的,有了valgrind错误,我们可以看到(a)你将狡猾的东西传递给printf
(如果你使用-g
进行编译,你将会得到确切的行号),你也在调用realloc
但不是从malloc
返回的指针。也许你已经完成了一些指针运算?
如果没有看到代码就说不出更多,但我希望你能找到valgrind很有帮助。
答案 3 :(得分:0)
你有几个一对一的错误:
for(i = 0; i < argc; i++)
while(calc > 0)