-2

終了しようとしているこの小さな演習がありますが、これまでに見たことのないエラーが発生します。それは私には論理的ではないようです:

oop244_a1.exeの0x0003191aで未処理の例外:0xC0000005:アクセス違反の読み取り場所0x003134d4。

プログラムコードは次のとおりです 。関数はボタン(bit_to_ascii)にあり、ここで問題が発生しています。プログラムのデバッグを試みましたが、変数'clen'が、そのループで950文字であると想定されているときに、何らかの理由で不当に高い数値(100000+)に変更されたようです。

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

#define LINES 5

/* assignment #1 function prototype */
int bit_to_ascii(const char [ ], char [ ]);

int main( ) {

   const char *core_data[ ] = {
"0", /* should insert the null byte '\0' only */

"01010111 This sequence contains the letter 'W'       " /*  87 = 'W' */
"      r5 0 #! 1 1 gP 0 f66-:] 0 [ } 1 v4t^ 0 1 n>?:77" /* 101 = 'e' */
" junk ^*@&#^% 0110  more junk }{r;,<> 1100         2x" /* 108 = 'l' */
"                  0    1       1     0 0          011" /*  99 = 'c' */
"0  ^%jh  1 ]{) OVR 1 - 0 _! 9 + 1  118Y z(x pM1      " /* 111 = 'o' */
"This next group of 8 should be SKP skipped! 11111111 " /* skipped */
"*&^! 0  1  1  0 1     1 0     128673kjshd:L<    2938 " /* 109 = 'm' */
"      r5 0 #! 1 1 gP 0 f66-:] 0 [ } 1 v4t^ 0 1 n>?:77" /* 101 = 'e' */
"#!/bin/bash 00  1 00 00 0 g^b-ps 6@&^%               " /*  32 = ' ' */
"01010100 This sequence contains the letter 'T'       " /*  84 = 'T' */
"0  ^%jh  1 ]{) OVR 1 - 0 _! 9 + 1  118Y z(x pM1      " /* 111 = 'o' */
"#!/bin/bash 00  1 00 00 0 g^b-ps 6@&^%               " /*  32 = ' ' */
"---repeat--->0 1 0 0 1 1 1 1<------------RPT2--------" /*  79 = 'O' */
"0 1 0 1 0bbavac9872962  000&*************************" /*  80 = 'P' */
"a0b0c1d1e0f0g1h0ijklmnopqrstuvwxyz*******************" /*  50 = '2' */
"00fg333                                110100>>>>>>>>" /*  52 = '4' */
"00fg333                                110100>>>>>>>>" /*  52 = '4' */
"                     0000                            ",/*  0 = '\0' */

"00011110 This char should not be inserted!           " /*  30 cntrl */
" 00011111 This char should not be inserted!          " /*  31 cntrl */
"  00100000                                           " /*  32 = ' ' */
"   00100001                                          " /*  33 = '!' */
"    00100010                                         " /*  34 = '"' */
"     00100011                                        " /*  35 = '#' */
"      00100100                                       " /*  36 = '$' */
"       00100101                                      " /*  37 = '%' */
"        00100110                                     " /*  38 = '&' */
"         00100111                                    " /*  39 = ''' */
"          00101000                                   " /*  40 = '(' */
"           00101001                                  " /*  41 = ')' */
"            00101010                                 " /*  42 = '*' */
"             00101011                                " /*  43 = '+' */
"              00101100                               " /*  44 = ',' */
"               00101101                              " /*  45 = '-' */
"                00101110                             " /*  46 = '.' */
"                 00101111                            " /*  47 = '/' */
"                  00110000                           " /*  48 = '0' */
"                   00110001                          " /*  49 = '1' */
"                    00110010                         " /*  50 = '2' */
"                     00110011                        " /*  51 = '3' */
"                      00110100                       " /*  52 = '4' */
"                       00110101                      " /*  53 = '5' */
"                        00110110                     " /*  54 = '6' */
"                         00110111                    " /*  55 = '7' */
"                          00111000                   " /*  56 = '8' */
"                           00111001                  " /*  57 = '9' */
"                            00111010                 " /*  58 = ':' */
"                             00111011                " /*  59 = ';' */
"                              00111100               " /*  60 = '<' */
"                               00111101              " /*  61 = '=' */
"                                00111110             " /*  62 = '>' */
"                                 00111111            " /*  63 = '?' */
"                                  01000000           " /*  64 = '@' */
"                                   00000000          ",/*   0 = '\0'*/

"                                    01000001         " /*  65 = 'A' */
"                                     01000010        " /*  66 = 'B' */
"                                      01000011       " /*  67 = 'C' */
"                                       01000100      " /*  68 = 'D' */
"                                        01000101     " /*  69 = 'E' */
"                                         01000110    " /*  70 = 'F' */
"                                          01000111   " /*  71 = 'G' */
"                                           01001000  " /*  72 = 'H' */
"                                            01001001 " /*  73 = 'I' */
"                                             01001010" /*  74 = 'J' */
"                                            01001011 " /*  75 = 'K' */
"                                           01001100  " /*  76 = 'L' */
"                                          01001101   " /*  77 = 'M' */
"                                         01001110    " /*  78 = 'N' */
"                                        01001111     " /*  79 = 'O' */
"                                       01010000      " /*  80 = 'P' */
"                                      01010001       " /*  81 = 'Q' */
"                                     01010010        " /*  82 = 'R' */
"                                    01010011         " /*  83 = 'S' */
"                                   01010100          " /*  84 = 'T' */
"                                  01010101           " /*  85 = 'U' */
"                                 01010110            " /*  86 = 'V' */
"                                01010111             " /*  87 = 'W' */
"                               01011000              " /*  88 = 'X' */
"                              01011001               " /*  89 = 'Y' */
"                             01011010                " /*  90 = 'Z' */
"                            01011011                 " /*  91 = '[' */
"                           01011100                  " /*  92 = '/' */
"                          01011101                   " /*  93 = ']' */
"                         01011110                    " /*  94 = '^' */
"                        01011111                     " /*  95 = '_' */
"                       01100000                      " /*  96 = '`' */
"                      00000000                       ",/*   0 = '\0'*/

"                     01100001                        " /*  97 = 'a' */
"                    01100010                         " /*  98 = 'b' */
"                   01100011                          " /*  99 = 'c' */
"                  01100100                           " /* 100 = 'd' */
"                 01100101                            " /* 101 = 'e' */
"                01100110                             " /* 102 = 'f' */
"               01100111                              " /* 103 = 'g' */
"              01101000                               " /* 104 = 'h' */
"             01101001                                " /* 105 = 'i' */
"            01101010                                 " /* 106 = 'j' */
"           01101011                                  " /* 107 = 'k' */
"          01101100                                   " /* 108 = 'l' */
"         01101101                                    " /* 109 = 'm' */
"        01101110                                     " /* 110 = 'n' */
"       01101111                                      " /* 111 = 'o' */
"      01110000                                       " /* 112 = 'p' */
"     01110001                                        " /* 113 = 'q' */
"    01110010                                         " /* 114 = 'r' */
"   01110011                                          " /* 115 = 's' */
"  01110100                                           " /* 116 = 't' */
" 01110101                                            " /* 117 = 'u' */
"01110110                                             " /* 118 = 'v' */
" 01110111                                            " /* 119 = 'w' */
"  01111000                                           " /* 120 = 'x' */
"   01111001                                          " /* 121 = 'y' */
"    01111010                                         " /* 122 = 'z' */
"     01111011                                        " /* 123 = '{' */
"      011111RPT10                                    " /* 124 = '|' */
"       01111101                                      " /* 125 = '}' */
"        00000000                                     " /*   0 = '\0'*/
};

   char phrase[41];
   char correct[LINES][41] = {
      "",
      "Welcome To OOP244",
      " !\"#$%&'()*+,-./0123456789:;<=>?@",
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`",
      "abcdefghijklmnopqrstuvwxyz{||||||||||}"
   };

   int rvalues[LINES] = { 1, 18, 34, 33, 39 }, i;
   int valid = 1, rc, err_code;

   for(i=0; i<LINES && valid; i++) {
      rc = bit_to_ascii(core_data[i], phrase);
      if(rc != rvalues[i] || strcmp(phrase, correct[i])) {
     printf("Failed on test... %d\n\n", i+1);
     valid = 0;
      }
      else {
     printf("Passed test %d...\n\n", i+1);
      }
      printf("Your string ----------> '%s'\n", phrase);
      printf("Actual string --------> '%s'\n", correct[i]);
      printf("Your return value ----> %d\n", rc);
      printf("Actual return value --> %d\n", rvalues[i]);
      printf("Press the ENTER key to continue...");
      getchar( );
   }
   if(valid) {
      printf("\nCongratualtions!!! You passed all tests.\n");
      printf("You may hand in your assignment.\n");
   }
   else {
      printf("\nYou correctly sequenced %d/5 data blocks...\n", i-1);
      printf("Your program still needs some work!\n");
      printf("Keep at it!\n\n");
   }
   getchar();
   return 0;
}

int bit_to_ascii(const char core[], char data[]) {
    int clen = strlen(core);
    int dlen = strlen(data);
    char bits[8] = {0,0,0,0,0,0,0,0};
    int bit_idx = 0;
    int i = 0;
    int dcount = 0;

    printf("clen: %d\n", clen);

    for (i = 0; i < clen; i++) {
        if (core[i] == '0' || core[i] == '1') {
            bits[bit_idx++] = core[i];

            //printf("bit_idx: %d\n", bit_idx);
            //printf("clen: %d\n", clen);
            //printf("i+1: %d\n", i+1);

            if (bit_idx == 8 || ((i+1) >= clen)) {

                int power = 7;
                double dec = 0.0;
                int j;

                // fill in with zeroes
                for (j = bit_idx; j < 8; j++) {
                    bits[j] = 0;
                }

                // binary to decimal
                for (j = 0; j < 8; j++) {
                    if (bits[j] == '1') {
                        dec += pow((double)2, power--);
                    }
                }

                data[dcount++] = (int)dec;
            }
        }
    }

    return dcount;
}
4

3 に答える 3

2

私はそれをテストしませんでしたが、おそらくあなたはにbit_idx達した後に「0」に設定する必要があります8

bitsそうでない場合は、配列から書き出してスタックを上書きします。おそらく、clen変数はたまたまそこにあります。

于 2012-05-27T20:36:43.860 に答える
1

問題はここにあります:

if (bit_idx == 8 || ((i+1) >= clen)) {
    ...
    for (j = bit_idx; j < 8; j++) {
        bits[j] = 0;
    }

forループに到達すると、 bit_idx8になる可能性があります。falseであるため、ループはラップアラウンドするまで(数百万回の反復後)8 < 8継続します。jしたがって、ある時点で、bits[j]アクセスできない(または無効な)メモリアドレスにアクセスするか、プログラムのデータ/スタックが破損する可能性があります。それが起こるとき、あなたのプログラムは(あなたが経験しているように)殺されます。

于 2012-05-27T20:40:36.560 に答える
0

そのプログラムであなたは一体何をしているのですか?

ああ、まあ、気にしないでください。数値が不当な値に変更されるというビジネスでは、データが破損しているように聞こえます。では、そのデータはどのように破損するのでしょうか。自動で割り当てられているので、スタック上にあります。これにより、呼び出された呼び出しパラメーターを確認できます。

しかし、それは2つの指針であり、そこで奇妙なことをする余地はあまりありません。

strlenが非常に高い価値を生み出す理由は何ですか?nullで終了していない文字列。

結論-これらの文字列の1つがnullで終了しない場合を探します。一定の長さなので、見たくなりますphrase。端から落ちやすいです。しかし、それは同じくらい簡単かもしれません

ああ、そしてデバッグシンボルが含まれているプログラムを再コンパイルして、スタックトレースをシンボル形式で見ることができるようにします。それはほぼ確実にあなたに答えを示すでしょう。

于 2012-05-27T20:43:20.390 に答える