2011-04-25 2 views
0

나는 그 오류가 내가 그것을 얻지 못한다는 것을 의미하는 오류를 세그먼트 오류로 제공하는 C 코드를 가지고있다. 여기에 코드입니다 :C 코드의 오류

#include <stdio.h> 
#include <assert.h> 
#include <stdlib.h> 
#include <string.h> 

#define STREQUAL(a,b) (strcmp(a,b) == 0) 

/* State of the 54-card deck. This keeps a spare deck for copying 
    into. It also has three spare slots *behind* the start of the 
    deck: two so the deck can be moved backward if a joker is moved 
    from the bottom to the top in the first step, and one so that the 
    reference to the card before the first joker always points 
    somewhere even when there's a joker on the top of the pack. */ 

typedef struct SolState_t { 
    int a, b; 
    int *deck, *spare; 
    int deck1[57], deck2[57]; 
} SolState_t ; 

SolState_t state; 

int verbose = 0; 
int lastout, cocount; 


#define JOKER_STEP(var,ovar) \ 
    (((var != 53) ? \ 
     (source[var] = source[var +1], var++) : \ 
     (source--, ovar++, source[0] = source[1], var = 1)), \ 
    ((var == ovar)?(ovar--):0)) 

/* Cycle the state for "rounds" outputs, skipping jokers 
    as usual. "lastout" is the last output, which is never a joker. 

    If "rounds" is zero though, cycle the state just once, even 
    if the output card is a joker. "lastout" may or may not be set. 
    This is only useful for key setup. 

    Note that for performance reasons, this updates the coincidence 
    statistics under all circumstances, so they need to be set to zero 
    immediately before the large batch run. */ 

static void cycle_deck(
    int rounds 
) 
{ 
    int *source, *s, *sb, *d; 
    int lo, hi; 
    int nlo, nhi, nccut; 
    int output; 

    do { 
     assert(state.a != state.b); 
     assert(state.deck[state.a] == 53); 
     assert(state.deck[state.b] == 53); 
     source = state.deck; 
     JOKER_STEP(state.a,state.b); 
     JOKER_STEP(state.b,state.a); 
     JOKER_STEP(state.b,state.a); 
     source[state.a] = 53; 
     source[state.b] = 53; 
     if (state.a < state.b) { 
      lo = state.a; 
      hi = state.b + 1; 
     } else { 
      lo = state.b; 
      hi = state.a + 1; 
     } 
     nlo = 54 - hi; 
     nhi = 54 - lo; 
      /* We do both the triple cut and the count cut as one 
       copying step; this means handling four separate cases. */ 
     nccut = source[lo -1]; 
     s = source; 
     if (lo == 0) { 
       /* There's a joker on the top of the pack. This can 
        only happen in one exact circumstance, but when it 
        does nccount is wrong. So we handle it specially. */ 
      assert(state.a == 0); 
      assert(state.b == 2); 
      d = &state.spare[51]; 
      sb = &source[3]; 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[0]; 
      sb = &source[54]; 
      while(s < sb) {*d++ = *s++;} 
      state.a = 51; 
      state.b = 53; 
     } else if (nccut <= nlo) { 
       /* The second cut is before the first joker. */ 
      d = &state.spare[nhi - nccut]; 
      sb = &source[lo -1]; 
      while(s < sb) {*d++ = *s++;} 
      state.spare[53] = *s++; 
      d = &state.spare[nlo - nccut]; 
      sb = &source[hi]; 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[53 - nccut]; 
      sb = &source[nccut + hi]; /* ccut */ 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[0]; 
      sb = &source[54]; 
      while(s < sb) {*d++ = *s++;} 
      state.a += nlo - nccut - lo; 
      state.b += nlo - nccut - lo; 
     } else if (nccut < nhi) { 
       /* The second cut is between the two jokers */ 
      d = &state.spare[nhi - nccut]; 
      sb = &source[lo -1]; 
      while(s < sb) {*d++ = *s++;} 
      state.spare[53] = *s++; 
      d = &state.spare[53 - nccut + nlo]; 
      sb = &source[nccut - nlo + lo]; /* ccut */ 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[0]; 
      sb = &source[hi]; 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[53 - nccut]; 
      sb = &source[54]; 
      while(s < sb) {*d++ = *s++;} 
      if (state.a < state.b) { 
       state.a = 53 - nccut + nlo; 
       state.b = nhi - nccut -1; 
      } else { 
       state.b = 53 - nccut + nlo; 
       state.a = nhi - nccut -1; 
      } 
     } else { 
       /* The second cut is after the last joker. */ 
      d = &state.spare[53 - nccut + nhi]; 
      sb = &source[nccut - nhi]; /* ccut */ 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[0]; 
      sb = &source[lo -1]; 
      while(s < sb) {*d++ = *s++;} 
      state.spare[53] = *s++; 
      d = &state.spare[53 - nccut + nlo]; 
      sb = &source[hi]; 
      while(s < sb) {*d++ = *s++;} 
      d = &state.spare[53 - nccut]; 
      sb = &source[54]; 
      while(s < sb) {*d++ = *s++;} 
      state.a += 53 - nccut + nlo - lo; 
      state.b += 53 - nccut + nlo - lo; 
     } 
     source = state.deck; 
     state.deck = state.spare; 
     state.spare = source; 
     output = state.deck[state.deck[0]]; 
     if (output >= 26) { 
      if (output >= 52) { 
       if (output > 52) 
        continue; 
       output = 0; 
      } else { 
       output -= 26; 
      } 
     } 
     cocount += (lastout == output); 
     lastout = output; 
     rounds--; 
    } while (rounds > 0); 
} 

static void print_deck(
) 
{ 
    int i; 

    for (i = 0; i < 54; i++) { 
    if (state.deck[i] < 53) { 
     putchar(' ' + state.deck[i]); 
    } else if (i == state.a) { 
     putchar('U'); 
    } else { 
     assert(i == state.b); 
     putchar('V'); 
    } 
    } 
} 

/* Key the deck with a passphrase. */ 

static void key_deck(
    char *key 
) 
{ 
    int i, kval, *tmp; 

    state.deck = state.deck1 + 3; 
    state.spare = state.deck2 + 3; 
    for (i = 0; i < 52; i++) { 
     state.deck[i] = i+1; 
    } 
    state.deck[state.a = 52] = 53; 
    state.deck[state.b = 53] = 53; 
    for (; *key != '\0'; key++) { 
     if (*key >= 'A' && *key <= 'Z') { 
      cycle_deck(0); /* Special value '0' is only useful here... */ 
       /* And now perform a second count cut based on the key letter */ 
      kval = *key - 'A' + 1; 
      for (i = 0; i < 53; i++) 
       state.spare[i] = state.deck[(i + kval) % 53]; 
      state.spare[53] = state.deck[53]; 
      if (state.a != 53) 
       state.a = (state.a + 53 - kval) % 53; 
      if (state.b != 53) 
       state.b = (state.b + 53 - kval) % 53; 
      tmp = state.deck; 
      state.deck = state.spare; 
      state.spare = tmp; 
     if (verbose) { 
      print_deck(); 
      printf(" after %c\n", *key); 
     } 
     } 
    } 
    /* These are touched by the keying: fix them. */ 
    lastout = 100; cocount = 0; 
} 

/* Encrypt a single character. */ 

static char encrypt_char(
    char char_in 
) 
{ 
    char char_out; 

    cycle_deck(1); 
    char_out = 'A' + (char_in - 'A' + lastout) % 26; 
    if (verbose) { 
     print_deck(); 
     printf(" %c -> %c\n", char_in, char_out); 
    } 
    return char_out; 
} 


int main(
    int argc, 
    char *argv[] 
) 
{ 
    char **av = argv, *tmp; 
    int slow_mode = 0; 
    long rounds; 

    /* Skip the name of the program */ 
    av++; argc--; 
    if (argc < 2) { 
     printf("Usage: [flags] key message|len\n"); 
    } 
    while (argc > 2) { 
     if (STREQUAL(*av, "-v")) { 
    verbose = 1; 
     } else if (STREQUAL(*av, "-s")) { 
    slow_mode = 1; 
     } else { 
    printf ("Unrecognised flag: %s\n", *av); 
    exit(-1); 
     } 
     av++; argc--; 
    } 
    key_deck(av[0]); 
    rounds = strtol(av[1], &tmp, 0); 
    if (*tmp != '\0') { 
     /* It's not a number - so it's a string! */ 
     char *text = av[1]; 
     int i = 0; 

     for (; *text != '\0'; text++) { 
    if (*text >= 'A' && *text <= 'Z') { 
     if (i > 0 && (i % 5) == 0) 
     putchar(' '); 
     putchar(encrypt_char(*text)); 
     i++; 
    } 
     } 
     while ((i % 5) != 0) { 
    putchar(encrypt_char('X')); 
    i++; 
     } 
     putchar('\n'); 
    } else { 
     /* Treat it as a sequence of 'A's. */ 
     int i; 

     if (rounds <= 0) { 
    printf("Rounds number must be greater than zero\n"); 
    exit(-1); 
     } 
     if (verbose || slow_mode) { 
    for (i = 0; i < rounds; i++) 
     encrypt_char('A'); 
     } else { 
    cycle_deck(rounds); 
     } 
     printf("Coincidences: %d/%ld\n", cocount, rounds -1); 
    } 
    return 0; 
} 
+7

네, 그런 일이 생길 때가 싫습니다. –

+0

몇 가지 코드를 보여줄 때까지 내가 볼 수있는 유일한 해결책에 대해 생각해 볼 때까지는 사이트에서 코드를 볼 때 100 달러/시간의 컨설턴트를 고용해야합니다. –

+0

해당 코드가 무엇인지 게시하십시오. 우리는 초능력이 아니며, 우리가 볼 수없는 코드에서 오류를 발견 할 수 없습니다. 또한 문제를 직접 처리하려고 시도한 내용을 게시하십시오. – MAK

답변

4

Segmentation fault.

당신의 편집에 대한 응답으로 답을 편집, GDB를 사용해보십시오 : 실행 : GDB MyApp.exe의 다음 명령이 "시작"을주고 그 이후 " 단계 "를 선택하십시오. 문제 영역을 하나의 특정 기능으로 좁히는 데 도움이됩니다.

디버깅 할 때 자세한 정보를 보려면 gcc를 사용하여 "-g"스위치를 사용하여 컴파일해야합니다. GDB의 전체 자습서를 사용할 수 있습니다. here

+0

정말 감사합니다. 오류를 찾기 위해 노력하고 있습니다. 감사 –

4

segmentation fault은 메모리 액세스 위반을 나타냅니다. 일반적으로 dangling pointer을 참조 해제하거나 C 언어로 프로그래밍 할 때 범위를 벗어나는 배열 인덱스에 액세스 한 결과입니다.

gdb을 사용하여 단계별로 세분화 오류가 발생한 위치를 확인하십시오.