base64解码函数:SIGSEGV ,,分段错误

时间:2011-12-12 11:45:08

标签: c

这是一个解码base64的函数。 SIGSEGV(有时它是SIGABORT)出现在被调用的malloc的行上。它几乎让我发疯!提前谢谢。

static char base64_table[255] = {'\0'};

static void base64_tableinit()
{
   int i,j;
   bzero(base64_table,255);
   for(j=0,i='A';i<='Z';i++) 
       base64_table[i]=j++;
   for(i='a';i<='z';i++)
       base64_table[i]=j++;
   for(i='0';i<='9';i++)
       base64_table[i]=j++;

   base64_table['+']=j++;
   base64_table['/']=j++;
   base64_table['=']=j;
}    
char *decode(const char *cptr,char **rptr)
{
    if(cptr==NULL)
    {
        fprintf (stderr, "The input string is NULL!\n");
        exit(1);
    }

    int len = strlen(cptr);
    if(len%4 != 0)  
    {
        fprintf (stderr, "The input string length is not 4X!\n");
        exit(1);
     }

     base64_tableinit();
     int clen=len/4;

#ifdef DEBUG
    /// printf ("The length of string len = %d\n",len);
    /// printf ("The length of string clen = %d\n",clen);
#endif
    char* res = NULL;
    /// Error: below, SIGSEGV
    if((res=(char *)malloc((len-clen + 1) * sizeof(char)))==NULL)
    {
        fprintf (stderr, "Can't malloc enough space in decode!\n");
        exit(1);
    }

    for(*rptr=res; clen>0; clen--)
    {
        *res = base64_table[(int)*cptr++]<<2 ;              /* Use the 1th char(6) */
        *res++|= base64_table[(int)*cptr]>>4 ;               /* Use the 2th char(2) */ /// Construct the first char 

        *res = base64_table[(int)*cptr++]<<4 ;              /* Use the 2th char(4) */
        *res++ |= base64_table[(int)*cptr]>>2 ;             /* Use the 3th char(4) */  /// Construct the second char 


        *res = base64_table[(int)*cptr++]<<6;               /* Use the 3th char(2) */
        *res++ |= base64_table[(int)*cptr++]&0x3f;          /* Use the 4th char(6) */  /// Construct the third char 

    }
    *(res+len-clen) = '\0';

    return *rptr;
}

gdb的回溯。

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb71a2b70 (LWP 5432)]
0xb7d450a6 in _int_malloc () from /lib/libc.so.6
(gdb) bt
0  0xb7d450a6 in _int_malloc () from /lib/libc.so.6
1  0xb7d4746c in malloc () from /lib/libc.so.6
2  0x0804b04c in decode (
cptr=0x806dce8  "PGRpdiBzdHlsZT0ibGluZS1oZWlnaHQ6MS43O2NvbG9yOiMwMDAwMDA7Zm9udC1zaXplOjE0cHg7Zm9udC1mYW1pbHk6YXJpYWwiPuato+W4uCA8YnI+PC9kaXY+PGJyPjxicj48c3BhbiB0aXRsZT0ibmV0ZWFzZWZvb3RlciI+PHNwYW4gaWQ9Im5ldGVhc2VfbWFp"..., rptr=0xb71a1fa8) at base64.c:78
3  0x0804d5af in email_decode (email_old=0xb71a1ffc, email_new=0xb71a1d50) at email_handle.c:421
4  0x0804a9c2 in PacketAnalyze () at packet_analyze.c:800
5  0xb7fa1cf2 in start_thread () from /lib/libpthread.so.0
6  0xb7da584e in clone () from /lib/libc.so.6

2 个答案:

答案 0 :(得分:1)

malloc中的分段错误是一个相当明确的信号,表明发生了一些疯狂的内存损坏,或者有人free指向非动态分配的内存。这两个错误不一定发生在您显示的代码或触发SIGSEGV的代码中。 但是,valgrind通常会检测到这两个错误。

答案 1 :(得分:0)

此:

*(res+len-clen) = '\0';

似乎错了,因为你已经在整个循环中增加了res,它应该只是

*res = '\0';