关于分段错误

时间:2012-06-06 15:10:33

标签: c segmentation-fault

我正在尝试使用UDP进行某种voip应用。我已经添加了RSA算法以确保安全。但是它给出了分段错误。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <stdlib.h>
#define LENGTH 3    /* how many seconds of speech to store */
#define RATE 8000   /* the sampling rate */
#define FILE_INPUT "/dev/dsp" /* Path to the sound card. */
#define FILE_OUTPUT "/dev/dsp"


/*-RSA-*/
//Her is gcd function
int gcd(int a,int b)
{
    while(a!=b){

        if(a>b)
            a-=b;
        else
            b-=a;
    }
    return a;
}


//This is called  Extended Euclid’s Algorithm to find d.

int findD(int e,int n)
{

    int f=e;
    int d=n;

    int x1, x2, x3, y1, y2, y3;
    x1 = 1; x2 = 0; x3 = f; //p
    y1 = 0; y2 = 1; y3 = d; //d



    int q = 0, i = 1;
    int t1 = 0, t2 = 0, t3 = 0;
    do
    {
        if (i == 1)
        {
            q = x3 / y3;
            t1 = x1 - (q * y1);
            t2 = x2 - (q * y2);
            t3 = x3 - (q * y3);
        }
        else
        {
            x1 = y1; x2 = y2; x3 = y3;
            y1 = t1; y2 = t2; y3 = t3;
            q = x3 / y3;
            t1 = x1 - (q * y1);
            t2 = x2 - (q * y2);
            t3 = x3 - (q * y3);
        }
        i++;


        if (y3 == 0)
        {
            break;
        }

    } while (y3 != 1);

    if (y3 == 0)
    {
        //printf("Sayinin tersi yoktur!!!!");
    }
    else
    {
        // printf("\nSayinin tersi : %d" , y2);
    }

    if(y2<=0)
    {

        y2=e+y2;

    }
    return y2;

}

//Instead of using pow function,I have choose to write square and multiply method which is faster and
//more suitable for big integers.Because we have no such a change to find 104^30 such like that
//Here computes pow(a,b)%n
int squareMul(int a,int b,int n)
{

    int y = 1;

    /*  Compute pow(a, b) % n using the binary square and multiply method. */
    while (b != 0)
    {
        /*  For each 1 in b, accumulate y. */
        if (b & 1)
        {
            y = (y * a) % n;
        }

        /* Square a for each bit in b. */
        a = (a * a) % n;

        /*  Prepare for the next bit in b. */
        b = b >> 1;
    }

    return y;

}
//Encyrption function
//Assume our plain-text is M
int *encyrpt(int text[],int e,int n)
{

    int t=0;
    int *s=(int *)malloc(100);

    for(t=0;t<sizeof(text);t++)
    {
        int gec=(int)text[t];

        //Here computes E(M)=M^e mod n;
        s[t]=squareMul(gec,e,n);

    }


    return s;


}

//Here is decyrption
//Assume our chipher-text is C
int *decyrpt(int enc[],int d,int e,int n)
{
    int i=0;
    int *s=(int *)malloc(100);

    for(i=0;i<sizeof(enc);i++)
    {
        int gelenEnc=(int)enc[i];
        //Here computes D(C)=C^d mod n;
        s[i]=squareMul(gelenEnc,d,n);


    }
    return s;

}



//Here is totient function to find prime to  m.
int totient(int m)
{

    int i;
    int ph=1;
    for(i=2;i<m;i++){

        if(gcd(i,m)==1)
        {
            ph=i;
            break;

        }
    }
    return ph;

}
/*-RSA-*/


int main()
{
    int sock,bytes_recv;
    struct sockaddr_in server_addr;
    struct hostent *host;
    char send_data[LENGTH*RATE];
    char recv_data[LENGTH*RATE];
    int addr_len, bytes_read;
    struct client_addr;


    /* this buffer holds the digitized audio */
    unsigned char buf[LENGTH*RATE];

    /*----------RSA-----------------------*/    

    //Here are some variables that I used for RSA ALGORİTHM
    //str is our plain-text
    char *plainText;
    int *ascii;
    int *enc;
    int *dec;
    int p,q;
    int k=0;
    int n;
    int e;
    int c;
    int phi;
    int d;

    plainText="Merhaba";

    //Here enter 2 relatively prime number
    //I have chose the p=73 and q=151

    p=73;
    q=151;

    printf("\n\ p :%d and q :%d \t \n",p,q);
    //Here computes n
    n = p*q;
    //Here computes phi func simply
    phi=(p-1)*(q-1);

    printf("\n\ n :\t= %d \n",n);
    printf("\n\ Phi :\t= %d \n",phi);

    //Here Euilers Totient function.It finds a number 'e' which is relatively prime with phi.
    e=totient(phi);
    //Here computes d,which is multiplicative inverse of e modula phi.
    d=findD(phi,e);

    printf("\n\ e :\t= %d  \n",e);

    printf("\n\ d :\t= %d which is multiplicative inverse of e modula phi \n",d);


    //Here is the ascii values for plainText.I have created new array in order to store plainText's ascii for simplicty
    ascii=(int *)malloc(sizeof(int)*sizeof(plainText)/sizeof(char));


/*---------------RSA------------*/


    int sound_device;

    /* open sound device */
    //I defined sound card both read and write mode for simplicity
    sound_device = open("/dev/dsp", O_RDWR);
    if (sound_device < 0) {
        perror("Open sound card failed");
        exit(1);
    }


    host= (struct hostent *) gethostbyname((char *)"127.0.0.1");


    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        perror("socket");
        exit(1);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5000);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(server_addr.sin_zero),8);


    while(1){

        read(sound_device, buf, sizeof(buf)); /* record some sound */

          printf("\n Size of buff: %d",sizeof(buf));
          ascii=malloc(LENGTH*RATE);
          buf=malloc(LENGTH*RATE);

                  printf("\n Size of ascii: %d",sizeof(ascii));

          //Here ascii stores plaintText's ascii number.
        for(c=0;c<LENGTH*RATE;c++)
        {

        int k=(int)buf[c];

        ascii[c]=k;
        printf("\n\t Ascii's of %c  \t= %d  \n",buf[c],ascii[c]);
            printf("\n\t C: %c  \t= %d  \n",c);
        }

         enc=encyrpt(ascii,e,n);


        //Send function to server
        sendto(sock, enc, LENGTH*RATE, 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr));

        //Listen from server for 3 seconds
        ioctl(sound_device, SOUND_PCM_SYNC, 0);
        bytes_recv = recvfrom(sock,buf,LENGTH*RATE,0,(struct sockaddr *)&server_addr, &addr_len);

        printf("\n Sended:");
        if(bytes_recv==LENGTH*RATE){

            printf("\nMessage received from server,listen:");
            //Here is decyription
            dec=decyrpt(buf,d,e,n);
            write(sound_device, dec, sizeof(dec));


            ioctl(sound_device, SOUND_PCM_SYNC, 0);
            }
    }

}


 Ascii's of �   = 131  

 C: �   = 10989  

分段错误

然而,我的RSA算法在其他char数组中正常运行。任何想法? 感谢

2 个答案:

答案 0 :(得分:2)

正如评论中的人们指出的那样,你应该使用调试器来找出确切发生分段错误的位置。

然而,粗略分析(开发人员在挖掘调试器之前应该总是这样做)显示了许多正在使用的指针。

每次拨打malloc时,都应该确认它是成功的。如果不是,并且您尝试使用malloc编辑的指针,则可以获得段错误。

您还可以为非malloc指针指定一个字符串(plainText)... BOOM:segfaults,啊!

您的一系列功能也会取消选中malloc

所以,你应该看一些地方。

答案 1 :(得分:2)

分段错误通常是由于尝试访问未为进程分配的内存而引起的。当您索引到数组(特别是动态创建的数组)时,通常会出现这种情况。

在您的代码中,您在malloc()encypt()函数中拥有固定大小的decrypt(),但您可以根据输入数组的大小访问其元素,可能成为seg.fault的原因。

可以肯定的是,您需要使用调试器并查看上/下索引发生的位置。一定要检查访问其他数组(无论是否动态分配)

此外,sizeof(plainText)返回指向字符的指针的大小,而不是字符串的长度。您需要将plaintext声明为基于堆栈的数组,或使用strlen()函数。