2012-11-21 68 views
1

我的程序有問題。我用一個虛擬的alfabeth做了一個簡單的編碼 - 編,但是當試圖訪問char數組時它不能訪問該位置,怎麼回事?我不知道它是否與size_t類型而不是int類型有關?爲什麼EXC_BAD_ACCESS,無法訪問內存?

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <time.h> 
#include <ctype.h> 

static char * createAlfa(void); 
char * codify(char *mess, char *alfa); 

int 
main(void) 
{ 
    char *alfa=createAlfa(); 
    printf("write your mess to codify: \n"); 
    char mess[]=""; 
    scanf("%s", mess); 
    char *code=codify(mess, alfa); 
    printf("your codified message is: %s\n", code); 
    return 0; 
} 

static char * 
createAlfa(void) 
{ 
    char *codealfa=malloc(sizeof(char)*27); 
    srand((unsigned int)time(NULL)); 
    int i, ran; 
    for(i=0; i<26; i++) 
    { 
     codealfa[i]='A'+i; 
     if((ran=rand()%26)<i) 
     { 
      codealfa[i]=codealfa[ran]; 
      codealfa[ran]='A'+i; 
     } 
    } 
    codealfa[26]=0; 
    return codealfa; 
} 

char * 
codify(char *mess, char *alfa) 
{ 
    size_t len=strlen(mess); 
    char *code=malloc(sizeof(char)*len); 
    int i; 
    for(i=0; i<len; i++) 
    { 
     int pos=(int)(toupper(mess[i])-'A'); //pos is behaving correctly, first loop is 
               //it is 15 when i write "potato" 
     code[i]=alfa[pos];  //EXC_BAD_ACCESS, Could not access memory 
    } 
    code[i]=0; 
    return code; 
} 
+0

你寫出我和pos作爲錯誤發生? –

+0

提示:循環退出時'i'的值是多少?那是在你用'malloc'創建的數組的範圍之內嗎? –

+0

你有一個錯誤的錯誤:'size_t len = strlen(mess); char * code = malloc(sizeof(char)* len);'in'codify()'。您需要添加1以爲null分配足夠的空間。警告:我進入了「馬鈴薯」並獲得了「編纂」輸出POTATO一次;這不是一個非常好的加密。 –

回答

3

您聲明mess爲:

char mess[]=""; 

這使得其大小等於1,持有NULL字符。接下來你正在掃描你輸入的數組:

scanf("%s", mess); 

這將無法正常工作,因爲沒有足夠的空間。

要解決此問題,您需要聲明mess正確的大小:比您打算存儲在其中的最大字符數的長度多一個。

+2

老鼠,打我吧 –

+0

+1,但這不是唯一的bug ... –

3

我相信這個問題是

char mess[]=""; 

沒有分配給字符串的內存被掃描到。

char mess[MAX_LENGTH]; 
mess[0] = 0; 

另外要注意,scanf函數,你使用它並不限制輸入的長度,看How to prevent scanf causing a buffer overflow in C?

3

當我在Mac OS X valgrind下運行的代碼替換它,我得到的輸出:

$ valgrind excbadacc 
==80786== Memcheck, a memory error detector 
==80786== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
==80786== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==80786== Command: excbadacc 
==80786== 
write your mess to codify: 
absintheabelones 
==80786== Invalid write of size 1 
==80786== at 0x100000D1B: codify (excbadacc.c:53) 
==80786== Address 0x100007210 is 0 bytes after a block of size 16 alloc'd 
==80786== at 0xB823: malloc (vg_replace_malloc.c:266) 
==80786== by 0x100000CC5: codify (excbadacc.c:45) 
==80786== 
==80786== Invalid read of size 1 
==80786== at 0xC894: strlen (mc_replace_strmem.c:398) 
==80786== by 0x1748C2: __vfprintf (in /usr/lib/system/libsystem_c.dylib) 
==80786== by 0x17318D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) 
==80786== by 0x17C2CF: printf (in /usr/lib/system/libsystem_c.dylib) 
==80786== by 0x100000DFA: main (excbadacc.c:18) 
==80786== Address 0x100007210 is 0 bytes after a block of size 16 alloc'd 
==80786== at 0xB823: malloc (vg_replace_malloc.c:266) 
==80786== by 0x100000CC5: codify (excbadacc.c:45) 
==80786== 
your codified message is: AQBRSKHDAQDPZSDB 
==80786== 
==80786== HEAP SUMMARY: 
==80786==  in use at exit: 10,330 bytes in 36 blocks 
==80786== total heap usage: 36 allocs, 0 frees, 10,330 bytes allocated 
==80786== 
==80786== LEAK SUMMARY: 
==80786== definitely lost: 43 bytes in 2 blocks 
==80786== indirectly lost: 0 bytes in 0 blocks 
==80786==  possibly lost: 0 bytes in 0 blocks 
==80786== still reachable: 10,287 bytes in 34 blocks 
==80786==   suppressed: 0 bytes in 0 blocks 
==80786== Rerun with --leak-check=full to see details of leaked memory 
==80786== 
==80786== For counts of detected and suppressed errors, rerun with: -v 
==80786== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1) 
$ 

的一個問題是,你有一個差一錯誤在codify()

size_t len=strlen(mess); 
char *code=malloc(sizeof(char)*len); 

您需要添加1以爲null分配足夠的空間。

警告:對於一次運行,我輸入了「馬鈴薯」並得到了「編纂」輸出POTATO;這不是一個非常好的加密。

+0

而且我看到這裏還有'mess'大小的問題。即使'valgrind'可以幫你做什麼也是有限度的。 –

+0

在一起,我們可以修復它:-) –

+0

@JonathanLeffler我已經解決了這個問題,但無論如何要感謝您的輸入,只能投票..我還沒有學習valgrind,但我在C程序中更多更重要的是它似乎是知道這個工具.. – patriques