我有以下代码来实现最大子序列长度搜索。我无法检查程序是否正确,因为运行我的程序会产生分段错误。
程序编译得很好。
请告诉我这里我做错了什么:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[6]={1,-2,4,33,0,-6}; //THE ACTUAL SEQUENCE
int count_a[6]={1,1,1,1,1,1}; //ARRAY TO KEEP COUNT OF MAXIMUM LENGTHS FROM POINT OF VIEW OF EACH ELEMENT OF ARRAY A
int i=0;
int j=0;
int k=0;
for(k=1;k<6;k++)
{
j=k;
printf("k's value:%d\t",j); //JUST FOR TESTING
while(1)
{
if(a[i]<a[j])
{
if(count_a[j]<(1+count_a[i]))
{
count_a[j]=1+count_a[i];
}
}
if(j-1==1)
{
break;
}
else
{
i++;
}
}
i=0;
}
/* THIS IS FOR ME TO CHECK WHETHER THE LENGTH VALUES HAVE BEEN UPDATED IN THE COUNT_A ARRAY*/
for(k=0;k<6;k++)
{
printf("%d\t",count_a[k]);
}
return 0;
}
答案 0 :(得分:2)
你有无限循环。 j=k;
然后while(1)
只能在if(j-1==1)
时终止。在第一次迭代k
设置为1
,因此j
也设置为1
。永远不要因为1-1!=1
而休息。您的j
永远不会在while(1)
循环中更改。
i++
始终是选项。当i
变大时,它会尝试从数组count_a[i]
外部读取,从而导致段错误。
答案 1 :(得分:2)
让我们使用clang's address sanitizer来弄清楚发生了什么:
[3:41pm][wlynch@watermelon /tmp] clang -g -fsanitize=address blah.c
[3:41pm][wlynch@watermelon /tmp] ./a.out
=================================================================
==22763==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff52950958 at pc 0x00010d2b0953 bp 0x7fff52950910 sp 0x7fff52950908
READ of size 4 at 0x7fff52950958 thread T0
#0 0x10d2b0952 in main blah.c:20
#1 0x7fff851205ac in start (/usr/lib/system/libdyld.dylib+0x35ac)
#2 0x0 (<unknown module>)
Address 0x7fff52950958 is located in stack of thread T0 at offset 56 in frame
#0 0x10d2b072f in main blah.c:8
This frame has 2 object(s):
[32, 56) 'a' <== Memory access at offset 56 overflows this variable
[96, 120) 'count_a'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow blah.c:20 main
Shadow bytes around the buggy address:
0x1fffea52a0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1fffea52a120: 00 00 00 00 f1 f1 f1 f1 00 00 00[f2]f2 f2 f2 f2
0x1fffea52a130: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
0x1fffea52a140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffea52a170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==22763==ABORTING
k's value:1 Abort
因此,您可以在a[]
结束后访问。
如果我减少你的代码,我们可以看到这显然是可能的:
k = 1;
j = k;
while(1)
{
if(a[i]<a[j])
if(count_a[j]<(1+count_a[i]))
count_a[j]=1+count_a[i];
if(j-1==1)
break;
else
i++;
}
请注意,j-1
在此次迭代中从不等于1
(它始终为0
),因此您将增加i
直到它已经过了a
。