Segmentation fault
[转,原文链接]
摘要 Segmentation fault 一般有是以下原因: 1)访问系统数据区,尤其是往系统保护的内存地址写数据最常见就是给一个指针以0地址。 2)内存越界(数组越界,变量类型不一致等): 访问到不属于你的内存区域。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #include <math.h> 5 #include <string.h> 6 7 #define ROW 370 8 #define COL 740 9 #define pi 3.1415926 10 #define times 10 //码流组数 11 #define LOOP 50 //每个DB值循环次数 12 //------------------------------------------------------------------- 13 //------------------------------------------------------------------- 14 typedef unsigned char UINT8; 15 typedef unsigned int UINT16; 16 typedef unsigned int UINT32; 17 typedef char INT8; 18 typedef int INT16; 19 typedef int INT32; 20 //------------------------------------------------------------------- 21 void genH(INT16 row,INT16 col); 22 //------------------------------------------------------------------- 23 void showH(); 24 //------------------------------------------------------------------- 25 void encode(bool s[],INT8 H[][COL],bool input[]); 26 //------------------------------------------------------------------- 27 void bpsk(bool input[],INT16 amp,INT16 tx_waveform[]); 28 //------------------------------------------------------------------- 29 void awgn(INT16 tx_waveform[],double rx_waveform[],INT16 length,double SNR); 30 //------------------------------------------------------------------- 31 void wgn(INT16 length,double noisepower,double noise_s[]); 32 //------------------------------------------------------------------- 33 void randn(double noise[],INT16 length); 34 //------------------------------------------------------------------- 35 void bp_decode(double rx_waveform[],double SNR_db,INT16 amp,INT8 H[][COL], 36 INT16 rearranged_cols[],bool output[]); 37 //------------------------------------------------------------------- 38 double atanh(double x); 39 //------------------------------------------------------------------- 40 INT16 sgn(double x); 41 struct original_bp 42 { 43 float qmn0; 44 float qmn1; 45 float dqmn; 46 float rmn0; 47 float rmn1; 48 float qn0; 49 float qn1; 50 float alpha; 51 }; 52 //------------------------------------------------------------------- 53 static INT8 H[ROW][COL]={0}; 54 //------------------------------------------------------------------- 55 static INT16 rearranged_cols[ROW]={0}; 56 //------------------------------------------------------------------- 57 58 double SNR_db,SNR,dbnum;//SNR:信噪比 59 int main() 60 { 61 bool s[times*(COL-ROW)],input[times*COL],output[times*(COL-ROW)]; 62 bool stage_s[COL-ROW],stage_input[COL],stage_output[COL-ROW]; 63 INT16 tx_waveform[times*COL],i,j,loop; 64 int error_num=0; 65 double rx_waveform[times*COL]={0},stage_rx[COL]={0}; 66 srand( (unsigned)time( NULL ) );//用即时的系统时间来做随机数种子.生成随机数 67 clock_t start,period; 68 69 INT16 amp;//振幅 70 double error_p;//误码率 71 //double SNR_db,SNR,dbnum;//SNR:信噪比 72 73 //配置信道信息 74 amp=1; 75 //循环多次提高平均性 76 start=clock(); 77 //产生H矩阵 78 genH(ROW,COL); 79 period=clock(); 80 printf("产生H矩阵用时%d\n",clock()); 81 //showH(); 82 83 for (dbnum=0;dbnum<=4;dbnum+=0.1) 84 { 85 SNR_db=dbnum; 86 SNR=pow(10.0,(SNR_db/10)); 87 for (int loop=0;loop<LOOP;loop++) 88 { 89 //产生全零码字 90 for (int i=0;i<times*(COL-ROW);i++) 91 { 92 s[i]=bool(0); 93 } 94 //用H矩阵进行编码 95 /*for (int i=0;i<times;i++) 96 { 97 for (int j=0;j<COL-ROW;j++)//把s[i]的值赋给stage_s[j] 98 { 99 stage_s[j]=s[i*(COL-ROW)+j]; 100 } 101 encode(stage_s,H,stage_input); 102 103 for (int j=0;j<COL;j++) 104 { 105 input[i*COL+j]=stage_input[j]; 106 } 107 }*/ 108 109 //进行BPSK调制 110 bpsk(input,amp,tx_waveform); 111 //加高斯白噪声 112 awgn(tx_waveform,rx_waveform,times*COL,SNR); 113 114 //解码 115 for (int i=0;i<times;i++) 116 { 117 for (int j=0;j<COL;j++) 118 { 119 stage_rx[j]=rx_waveform[i*COL+j]; 120 } 121 //原始BP译码算法 122 printf("SNR_ads:%p\n",&SNR); 123 bp_decode(stage_rx,SNR,amp,H,rearranged_cols,stage_output); 124 for (int j=0;j<COL-ROW;j++) 125 { 126 output[i*(COL-ROW)+j]=stage_output[j]; 127 } 128 } 129 130 for (int i=0;i<times*(COL-ROW);i++) 131 { 132 if (s[i]!=output[i]) 133 { 134 error_num++; 135 } 136 } 137 }//endofloop 总循环 138 printf("本次db值循环用时:%d\n",clock()-period); 139 period=clock(); 140 error_p=(1.0*error_num)/(LOOP*times*(COL-ROW)); 141 printf("%d个码,SNR=%3.3fdb,误码个数为%f,误码率为%lf\n",times*(COL-ROW),SNR_db,(1.0*error_num)/LOOP,error_p); 142 if(error_p==0) 143 break; 144 error_num=0; 145 }//endof db循环 146 printf("原始码字:\n"); 147 for (i=0;i<times*(COL-ROW);i++) 148 { 149 printf("%d ",s[i]); 150 } 151 printf("\n"); 152 printf("输出码字:\n"); 153 for (i=0;i<times*(COL-ROW);i++) 154 { 155 printf("%d ",output[i]); 156 } 157 158 return 0; 159 } 160 161 ////////////////////////////////////////////////////////////////////////// 162 //生成校验矩阵H 163 void genH(INT16 row,INT16 col) 164 { 165 INT16 row_flag[ROW]={0};//每一行1的个数 166 INT16 bit_per_col=3;//列重3 167 INT16 row_num[3]={0};//一列中1的横坐标 168 INT16 max_ones_per_row=0;//每一行1的最多个数 169 INT16 i,j,k,r,newrow,loop,common,thecol,col_rearranged,looptwo; 170 bool ckfinish,flag; 171 INT16 ones_position[ROW/2]={0},ones_count=0;//每一行中1的位置及1的个数。 172 173 srand( (unsigned)time( NULL ) );//用即时的系统时间来做随机数种子.生成随机数 174 //每列随机产生3个1 175 for (j=0;j<COL;j++) 176 { 177 for (i=0;i<bit_per_col;i++) 178 { 179 row_num[i]=rand()%ROW; 180 //避免产生的随机行重复 181 while (i==1&&row_num[i]==row_num[0]) 182 { 183 row_num[i]=rand()%ROW; 184 } 185 while (i==2&&(row_num[i]==row_num[0]||row_num[i]==row_num[1])) 186 { 187 row_num[i]=rand()%ROW; 188 } 189 190 H[row_num[i]][j]=1; 191 row_flag[row_num[i]]++;//记录每一行1的个数 192 } 193 }//end of 每列产生3个随机1 194 195 196 max_ones_per_row=ceil(COL*bit_per_col*1.0/ROW); 197 198 /* // [12/3/2011 by qjf]貌似不用补1 199 for (i=0;i<ROW;i++) 200 { 201 //如果该行没有1,则随机添加两个1 202 if (row_flag[i]==0) 203 { 204 for (k=0;k<2;k++) 205 { 206 j=rand()%COL; 207 while (H[i][j]==1) 208 { 209 j=rand()%COL; 210 } 211 H[i][j]=1; 212 row_flag[i]++; 213 } 214 }//end of if(row_flag[i]==0) 215 //如果该行只有1个1,则随机再增加1个 216 if (row_flag[i]==1) 217 { 218 j=rand()%COL; 219 while (H[i][j]==1) 220 { 221 j=rand()%COL; 222 } 223 H[i][j]=1; 224 row_flag[i]++; 225 }//end of if (row_flag[i]==1) 226 }//end of for i=0:ROW-1 227 */ 228 229 //在列上分散1的位置,使得每行1的个数相等或相近 230 loop=10; 231 for (loop=0;loop<10;loop++) 232 { 233 flag=1; 234 for (i=0;i<ROW;i++) 235 { 236 while (row_flag[i]>max_ones_per_row) 237 { 238 flag=0;//有一行中的1大于最大允许 239 j=rand()%COL; 240 if (H[i][j]==1)//随机选择该行上某一为1的列,将该列该行上的这个1分散到其他行 241 { 242 newrow=rand()%ROW;//随机查找新的行 243 k=0; 244 while ((row_flag[newrow]>=max_ones_per_row||H[newrow][j]==1)&&k<ROW) 245 { 246 newrow=rand()%ROW; 247 k++; 248 } 249 if (H[newrow][j]==0) 250 { 251 H[newrow][j]=1; 252 row_flag[newrow]++; 253 H[i][j]=0; 254 row_flag[i]--; 255 } 256 257 }//end of if H[][]==1 258 }//end of while 259 }//end of for i=0:row-1 260 if (flag==1) 261 break; 262 263 }//end of loop 264 265 //去除4环性 266 loop=10; 267 for (k=0;k<loop;k++) 268 { 269 ckfinish=1;//bool型变量 270 for (r=0;r<ROW;r++) 271 { 272 //记录每一行1的位置 273 ones_count=0; 274 for (j=0;j<COL;j++) 275 if (H[r][j]==1) 276 { 277 ones_position[ones_count]=j; 278 ones_count++; 279 } 280 281 for (i=0;i<ROW;i++)//遍历其他行 282 { 283 common=0;// 284 if (i!=r)//与除该行外的其他行进行比较 285 { 286 for (j=0;j<ones_count;j++) 287 { 288 if (H[i][ones_position[j]]==1) 289 { 290 common++; 291 if (common==1) 292 { 293 thecol=ones_position[j];//有重叠1的列 294 } 295 }//endof if H[][]==1 296 if (common==2) 297 { 298 ckfinish=0;//检测到存在4环现象,循环不结束,继续进行 299 common--; 300 if (rand()%2==0)//随机决定保留前面列还是后面列 301 { 302 col_rearranged=thecol;//保留后面的列, 303 thecol=ones_position[j]; 304 } 305 else 306 col_rearranged=ones_position[j];//保留前面的列,交换后面的列 307 /************有待考证*******************************************/ 308 //被交换列的1置为3 309 H[i][col_rearranged]=3; 310 newrow=rand()%ROW; 311 looptwo=0; 312 while (H[newrow][col_rearranged]!=0 && looptwo<5)//只搜索为0的 313 { 314 newrow=rand()%ROW; 315 looptwo++; 316 } 317 if (looptwo>=5)//超过5次后搜索范围扩大到所有0和3 318 { 319 while (H[newrow][col_rearranged]==1) 320 { 321 newrow=rand()%ROW; 322 } 323 } 324 H[newrow][col_rearranged]=1; 325 }//endof if common==2 326 /*****************************************************************/ 327 }//endof for j=0:ones_count-1 328 }//endof if r!=i 329 }//遍历其他行 330 }//endof for i=0:ROW-1 331 332 if (ckfinish==1)//如果本次循环已经不存在四环,则循环结束 333 { 334 printf("breakloop=%d\n",k); 335 break; 336 } 337 }//end of loop 338 339 //将所有的3变为0 340 for (i=0;i<ROW;i++) 341 for(j=0;j<COL;j++) 342 { 343 if (H[i][j]==3) 344 { 345 H[i][j]=0; 346 } 347 } 348 //H矩阵生成成功 349 } 350 351 ////////////////////////////////////////////////////////////////////////// 352 //显示H矩阵 353 void showH() 354 { 355 INT16 num_ones=0; 356 printf("H矩阵:\n"); 357 for (INT16 i=0;i<ROW;i++) 358 { 359 for (int j=0;j<COL;j++) 360 { 361 printf("%d",H[i][j]); 362 if (H[i][j]==1) 363 { 364 num_ones++; 365 } 366 367 } 368 printf("\n"); 369 } 370 printf("%d\n",num_ones); 371 } 372 ////////////////////////////////////////////////////////////////////////// 373 //用校验矩阵对码流进行编码 374 void encode(bool s[],INT8 H[][COL],bool input[]) 375 { 376 bool mid_H[ROW][COL],G[COL][COL-ROW]={0},Isempty; 377 INT16 i,j,k,r,G_row=COL,G_col=COL-ROW,sum,temp; 378 379 for (i=0;i<ROW;i++) 380 for(j=0;j<COL;j++)//将矩阵H赋值给矩阵mid_H 381 { 382 mid_H[i][j]=H[i][j]; 383 } 384 //将H矩阵转换为[I P]形式 385 386 for (r=0;r<ROW;r++)//逐行进行高斯消元 387 { 388 //查找可以使H(r,r)=1的列 389 j=r; 390 391 while (j<COL&&mid_H[r][j]==0) 392 { 393 Isempty=1; 394 for (i=r+1;i<ROW;i++) 395 { 396 if (mid_H[i][j]==1) 397 Isempty=0; 398 } 399 if (!Isempty)//找到符合要求的列 400 break; 401 j++; 402 } 403 if (j>=COL)//如果找不到可以交换的列,则视为非法H矩阵 404 { 405 printf("非法H矩阵!!!\n"); 406 } 407 //如果不是当前列则进行列交换 408 if (j!=r) 409 { 410 rearranged_cols[r]=j; 411 for (i=0;i<ROW;i++) 412 { 413 temp=mid_H[i][r]; 414 mid_H[i][r]=mid_H[i][j]; 415 mid_H[i][j]=temp; 416 } 417 } 418 419 //高斯消元,让H(r,r)=1 420 421 if (mid_H[r][r]==0) 422 { 423 i=r; 424 while(mid_H[i][r]==0 && i<ROW) 425 { 426 i++; 427 } 428 if (i>=ROW) 429 { 430 printf("高斯消元错误\n"); 431 } 432 if (mid_H[i][r]==1) 433 { 434 for (j=r;j<COL;j++)//两行相加 435 { 436 mid_H[r][j]=(mid_H[r][j]+mid_H[i][j])%2; 437 } 438 } 439 }//endof 让H(r,r)=1 440 441 //高斯消元,让第r列除r行以外的所有行都为0 442 for (i=0;i<ROW;i++) 443 { 444 if (i!=r)//除r行外 445 { 446 if (mid_H[i][r]==1) 447 { 448 for (j=r;j<COL;j++) 449 { 450 mid_H[i][j]=(mid_H[r][j]+mid_H[i][j])%2; 451 } 452 } 453 } 454 }//endof 让r列除r外每行都为0 455 456 }//endof for逐行高斯消元 457 458 /*****检验IP矩阵******/ 459 /* printf("IP矩阵:\n"); 460 INT16 num_ones=0; 461 for (i=0;i<ROW;i++) 462 { 463 for (j=0;j<COL;j++) 464 { 465 printf("%d",mid_H[i][j]); 466 if (mid_H[i][j]==1) 467 { 468 num_ones++; 469 } 470 471 } 472 printf("\n"); 473 //printf("\t%d\n",num_ones); 474 } 475 printf("%d\n",num_ones); 476 */ 477 //将H矩阵变成G矩阵 478 479 for (i=0;i<ROW;i++) 480 for (j=ROW;j<COL;j++) 481 { 482 G[i][j-ROW]=mid_H[i][j]; 483 } 484 for (i=ROW;i<COL;i++) 485 for (j=0;j<COL-ROW;j++) 486 { 487 if (i-ROW==j) 488 { 489 G[i][j]=1; 490 } 491 } 492 /*//测试G矩阵 493 printf("G矩阵:\n"); 494 num_ones=0; 495 for (i=0;i<COL;i++) 496 { 497 for (j=0;j<COL-ROW;j++) 498 { 499 printf("%d",G[i][j]); 500 if (G[i][j]==1) 501 { 502 num_ones++; 503 } 504 505 } 506 printf("\n"); 507 // printf("\t%d\n",num_ones); 508 } 509 printf("%d\n",num_ones); 510 */ 511 512 //用G矩阵与序列相乘得到生成序列G*s' 513 for (i=0;i<G_row;i++) 514 { 515 sum=0; 516 for (j=0;j<G_col;j++) 517 { 518 sum=sum+G[i][j]*s[j]; 519 } 520 input[i]=sum%2; 521 } 522 523 //根据rearranged_cols中记录的变换,将编码序列变回来 524 for (i=ROW-1;i>=0;i--) 525 { 526 if (rearranged_cols[i]!=0) 527 { 528 temp=input[i]; 529 input[i]=input[rearranged_cols[i]]; 530 input[rearranged_cols[i]]=temp; 531 } 532 533 } 534 } 535 536 ////////////////////////////////////////////////////////////////////////// 537 //用BPSK进行调制 538 void bpsk(bool input[],INT16 amp,INT16 tx_waveform[]) 539 { 540 INT16 i; 541 for (i=0;i<times*COL;i++) 542 { 543 if (input[i]==1) 544 tx_waveform[i]=amp; 545 else 546 tx_waveform[i]=-amp; 547 } 548 } 549 ////////////////////////////////////////////////////////////////////////// 550 //调制后信号通过AWGN 551 void awgn(INT16 tx_waveform[],double rx_waveform[],INT16 length,double SNR) 552 { 553 INT16 i,sum=0; 554 double sigpower,noisepower,noise_s[times*COL]; 555 556 /* for (i=0;i<length;i++) 557 { 558 rx_waveform[i]=double(tx_waveform[i]); 559 } 560 */ 561 for (i=0;i<length;i++) 562 { 563 sum=sum+tx_waveform[i]*tx_waveform[i]; 564 } 565 sigpower=(1.0*sum)/length; 566 567 //计算所需的噪声功率,这里用的SNR单位不是db 568 noisepower=sigpower/SNR; 569 //产生高斯白噪声 570 wgn(length,noisepower,noise_s); 571 572 //加噪声 573 for (i=0;i<length;i++) 574 { 575 rx_waveform[i]=tx_waveform[i]+noise_s[i]; 576 } 577 } 578 ////////////////////////////////////////////////////////////////////////// 579 //产生高斯白噪声 580 void wgn(INT16 length,double noisepower,double noise_s[]) 581 { 582 INT16 i; 583 double random_s[times*COL],imp; 584 //产生高斯分布序列 585 randn(random_s,length); 586 587 imp=sqrt(1.0*noisepower); 588 for (i=0;i<length;i++) 589 { 590 noise_s[i]=imp*random_s[i]; 591 } 592 } 593 ////////////////////////////////////////////////////////////////////////// 594 //产生高斯分布序列 595 void randn(double random_s[],INT16 length) 596 { 597 double x1[times*COL],x2[times*COL]; 598 INT16 i; 599 srand( (unsigned)time( NULL ) ); 600 for(i=0;i<length;i++) 601 { 602 x1[i]=(1.0*rand())/RAND_MAX; 603 x2[i]=(1.0*rand())/RAND_MAX; 604 random_s[i]=sqrt(-2*log(x1[i]))*cos(x2[i]*pi); 605 } 606 } 607 ////////////////////////////////////////////////////////////////////////// 608 //用原始BP算法进行解码 609 void bp_decode(double rx_waveform[],double SNR,INT16 amp,INT8 H[][COL],INT16 rearranged_cols[],bool output[]) 610 { 611 struct original_bp newh[ROW][COL]={0}; 612 float p11[COL],p10[COL],drmn,prod_rmn0,prod_rmn1,const1,const2,const3,const4,alpha_n; 613 INT16 i,j,k,r,iteration,sum; 614 INT16 ones_position[COL]={0},ones_count=0; 615 bool mid_out[COL],Iszero,temp; 616 //先验概率 617 for (i=0;i<COL;i++) 618 { 619 p11[i]=1/(1+exp(-2*amp*rx_waveform[i]*2*SNR));//N0/2=方差 620 p10[i]=1-p11[i]; 621 } 622 //初始化:对特定信道预设信息比特的先验概率 623 624 for (i=0;i<ROW;i++) 625 for (j=0;j<COL;j++) 626 { 627 if (H[i][j]==1) 628 { 629 newh[i][j].qmn0=p10[j]; 630 newh[i][j].qmn1=p11[j]; 631 newh[i][j].alpha=1.0; 632 } 633 } 634 //showH(); 635 //迭代100次 636 iteration=100; 637 for (r=0;r<iteration;r++) 638 { 639 //横向步骤:置信概率由信息节点传输到校验节点 640 641 for (i=0;i<ROW;i++)//计算概率差 642 for (j=0;j<COL;j++) 643 { 644 if (H[i][j]==1) 645 { 646 newh[i][j].dqmn=newh[i][j].qmn0-newh[i][j].qmn1; 647 } 648 } 649 650 for (i=0;i<ROW;i++) 651 { 652 ones_count=0; 653 for (j=0;j<COL;j++)//记录该行 为1的列数 654 { 655 if (H[i][j]==1) 656 { 657 ones_position[ones_count]=j; 658 ones_count++; 659 } 660 } 661 for (j=0;j<ones_count;j++) 662 { 663 drmn=1.0; 664 for (k=0;k<ones_count;k++) 665 { 666 if (k!=j) 667 { 668 drmn=drmn*newh[i][ones_position[k]].dqmn; 669 } 670 } 671 newh[i][ones_position[j]].rmn0=(1+drmn)/2; 672 newh[i][ones_position[j]].rmn1=(1-drmn)/2; 673 ////////////////////////////////////////////////////////////////////////// 674 675 } 676 } 677 //纵向步骤:由校验节点向信息节点传输信息 678 for (j=0;j<COL;j++) 679 { 680 ones_count=0; 681 for (i=0;i<ROW;i++)//记录该列 为1的行数 682 { 683 if (H[i][j]==1) 684 { 685 ones_position[ones_count]=i; 686 ones_count++; 687 } 688 } 689 for (i=0;i<ones_count;i++) 690 { 691 prod_rmn0=1.0; 692 prod_rmn1=1.0; 693 for (k=0;k<ones_count;k++) 694 { 695 if (k!=i) 696 { 697 prod_rmn0=prod_rmn0*newh[ones_position[k]][j].rmn0; 698 prod_rmn1=prod_rmn1*newh[ones_position[k]][j].rmn1; 699 } 700 } 701 const1=p10[j]*prod_rmn0; 702 const2=p11[j]*prod_rmn1; 703 newh[ones_position[i]][j].alpha=1.0/(const1+const2); 704 newh[ones_position[i]][j].qmn0=newh[ones_position[i]][j].alpha*const1; 705 newh[ones_position[i]][j].qmn1=newh[ones_position[i]][j].alpha*const2; 706 707 //更新伪后验概率,因为每列都是一样的qn0qn1,所以只计算每列最后一个就可以. 708 //经过上面的纵向循环,i-1为ones_position的最后一项 709 const3=const1*newh[ones_position[i]][j].rmn0; 710 const4=const2*newh[ones_position[i]][j].rmn1; 711 alpha_n=1.0/(const3+const4); 712 newh[ones_position[i]][j].qn0=alpha_n*const3; 713 newh[ones_position[i]][j].qn1=alpha_n*const4; 714 //译码尝试,对信息节点的后验概率作硬判决 715 if (newh[ones_position[i]][j].qn1>0.5) 716 mid_out[j]=1; 717 else 718 mid_out[j]=0; 719 } 720 }//endof 纵向 721 722 //如果判决条件满足,则停止译码 723 724 725 for (i=0;i<ROW;i++) 726 { 727 Iszero=1; 728 sum=0; 729 for (j=0;j<COL;j++) 730 { 731 sum=sum+H[i][j]*mid_out[j]; 732 } 733 if (sum%2!=0) 734 { 735 Iszero=0; 736 } 737 if (Iszero==0)//若有一行作乘后不为0,则判决不满足 738 { 739 // printf("判决不满足\n"); 740 break; 741 } 742 } 743 if (Iszero==1) 744 { 745 // printf("迭代%d次结束\n",r); 746 break; 747 } 748 }//迭代结束 749 750 //获得译码后的输出 751 for (i=0;i<ROW;i++) 752 { 753 if (rearranged_cols[i]!=0) 754 { 755 temp=mid_out[i]; 756 mid_out[i]=mid_out[rearranged_cols[i]]; 757 mid_out[rearranged_cols[i]]=temp; 758 } 759 } 760 for (i=ROW;i<COL;i++) 761 { 762 output[i-ROW]=mid_out[i]; 763 } 764 } 765 766 ////////////////////////////////////////////////////////////////////////// 767 //sgn函数 768 INT16 sgn(double x) 769 { 770 if (x>0) 771 return 1; 772 if (x<0) 773 return -1; 774 if (x==0) 775 return 0; 776 }