Using char as array index in C?

2019-09-08 06:41发布

问题:

I have this code:

int main(){

  char vector[52];
  char i;

  /* initialize the vector */
  for (i ='a'; i < 'z'; i++){
    vector[i] = i - 'a' + 1;
  } 
  // vector is like vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26


  for (i ='A'; i <= 'Z'; i++){
    vector[i] = i - 'A' + 27;
  }
  // vector is like vector['A'] = 27, vector['B'] = 28 .. vector['z'] = 52

  for (i ='a'; i <= 'z'; i++){
    printf("letter %c : %d \n", i, vector[i]);
  } 

  for (i ='A'; i <= 'Z'; i++){
    printf("letter %c : %d \n", i, vector[i]);
  }

  return 0;
}

Output :

letter a : 1 
letter b : 2 
letter c : 3 
letter d : 4 
letter e : 5 
letter f : 6 
letter g : 7 
letter h : 8 
letter i : 9 
letter j : 10 
letter k : 11 
letter l : 12 
letter m : 13 
letter n : 14 
letter o : 15 
letter p : 16 
letter q : 17 
letter r : 18 
letter s : 19 
letter t : 20 
letter u : 21 
letter v : 22 
letter w : 23 
letter x : 24 
letter y : 25 
letter z : 0 
letter A : 27 
letter B : 28 
letter C : 29 
letter D : 30 
letter E : 31 
letter F : 32 
letter G : 33 
letter H : 34 
letter I : 35 
letter J : 36 
letter K : 37 
letter L : 38 
letter M : 39 
letter N : 40 
letter O : 41 
letter P : 42 
letter Q : 43 
letter R : 44 
letter S : 45 
letter T : 46 
letter U : 47 
letter V : 48 
letter W : 49 
letter X : 50 
letter Y : 51 
letter Z : 52 
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x50)[0xc25df0]
/lib/i386-linux-gnu/libc.so.6(+0xe5d9a)[0xc25d9a]
./a.out[0x8048547]
[0x343332]
======= Memory map: ========
00110000-0012a000 r-xp 00000000 08:01 131939     /lib/i386-linux-gnu/libgcc_s.so.1
0012a000-0012b000 r--p 00019000 08:01 131939     /lib/i386-linux-gnu/libgcc_s.so.1
0012b000-0012c000 rw-p 0001a000 08:01 131939     /lib/i386-linux-gnu/libgcc_s.so.1
00a19000-00a1a000 r-xp 00000000 00:00 0          [vdso]
00aa4000-00ac0000 r-xp 00000000 08:01 131898     /lib/i386-linux-gnu/ld-2.13.so
00ac0000-00ac1000 r--p 0001b000 08:01 131898     /lib/i386-linux-gnu/ld-2.13.so
00ac1000-00ac2000 rw-p 0001c000 08:01 131898     /lib/i386-linux-gnu/ld-2.13.so
00b40000-00c9a000 r-xp 00000000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9a000-00c9b000 ---p 0015a000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9b000-00c9d000 r--p 0015a000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9d000-00c9e000 rw-p 0015c000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9e000-00ca1000 rw-p 00000000 00:00 0 
08048000-08049000 r-xp 00000000 08:01 40062      /home/valter/Documents/Complexidade/recursivo/a.out
08049000-0804a000 r--p 00000000 08:01 40062      /home/valter/Documents/Complexidade/recursivo/a.out
0804a000-0804b000 rw-p 00001000 08:01 40062      /home/valter/Documents/Complexidade/recursivo/a.out
0846f000-08490000 rw-p 00000000 00:00 0          [heap]
b7772000-b7773000 rw-p 00000000 00:00 0 
b7782000-b7785000 rw-p 00000000 00:00 0 
bfa50000-bfa71000 rw-p 00000000 00:00 0          [stack]
Aborted

I don't understand why is giving this error message. I should have a vector like this :

vector['a'] = 0, vector['b'] = 1,  .., vector['z'] = 26, vector['A'] = 27, vector['B'] = 28, .., vector['Z'] = 52

I understand that I have this vector but the error came with it. How solve this problem ?

回答1:

Because 'Z' is not equal to 'z'.

'Z' is equal to 90 and your vector only has 52 elements. Your highest index is 51 so you are basically going out of bounds!

For example when you are doing this

  for (i ='A'; i <= 'Z'; i++)
  {
    vector[i] = i - 'A' + 27;
  }

This is what your first iteration looks like:

vector[65] = 65 - 65 + 27; // <-- Wrong index !


回答2:

for (i ='A'; i <= 'Z'; i++){
    vector[i] = i - 'A' + 27;
}

Doesn't do what you think it does. 'A' means the ASCII value for the character A which is 65; your index is out of bounds immediately.



回答3:

char vector[52];

So, the accessible indexes of vector are 0 to 51. But -

for (i ='A'; i <= 'Z'; i++) // 'A' = 65 and 'Z' = 90
{
    printf("letter %c : %d \n", i, vector[i]);
}

There are no such indexes on the vector and result out of bounds exception.



回答4:

  char vector[52];
  for (i ='a'; i < 'z'; i++){
    vector[i] = i - 'a' + 1;
  } 

'a' is 97. Your array is only 52 long. You've blown the array with virtually your first executable statement.

I suspect you meant to say something like

    vector[i-'a] = something;

(Though I'm not quite sure what "something" might be.)



回答5:

First, a side note: your first for loop needs to include 'z' also. Therefore:

for (i ='a'; i <= 'z'; i++){

In C, arrays are not maps from any value to any value. They are just an array (or a contiguous list), starting from index 0. When you say

char vector[52];

means you have an array of size 52. Valid indices to the array are 0 to 51. However, when you write a character like 'a', it really is just a number which is the ascii code of character a (which is 0x61, that is 61 hex). The highest index you are using is 'z' which is 122. Therefore your array needs to have index 122 valid, therefore must have a size of at least 123.

So your code becomes like this:

int main(){

  char vector[123];
  char i;

  /* initialize the vector */
  for (i ='a'; i <= 'z'; i++){
    vector[i] = i - 'a' + 1;
  } 
  // vector is like vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26


  for (i ='A'; i <= 'Z'; i++){
    vector[i] = i - 'A' + 27;
  }
  // vector is like vector['A'] = 27, vector['B'] = 28 .. vector['z'] = 52

  for (i ='a'; i <= 'z'; i++){
    printf("letter %c : %d \n", i, vector[i]);
  } 

  for (i ='A'; i <= 'Z'; i++){
    printf("letter %c : %d \n", i, vector[i]);
  }

  return 0;
}

Also, there is a contradiction in your question. You say first that you have:

// vector is like vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26

then you say:

I should have a vector like this :

vector['a'] = 0, vector['b'] = 1,  .., vector['z'] = 26, vector['A'] = 27, vector['B'] = 28, .., vector['Z'] = 52

if you want to have vector['a'] starting from 0 rather than 1, you should change your formula from vector[i] = i - 'a' + 1; to vector[i] = i - 'a';