1

I use the following two lines of code:

enum bus_sigs {  REG0, REGA, REGB, REGC, REGD };
short bus[5];

The purpose is to index the array of shorts with the enum names. For example, I use: bus[REGA].

I am getting weird behavior: if I use bus[REGC] I am getting weird values as if I am fetching data from beyond the array memory range. If I then update the second line to:

short bus[10];

The behavior is again as expected. But this makes no sense to me. I am only ever assigning to 5 members in the bus array.

What am I not getting?

Jayesh Bhoi
  • 24,694
  • 15
  • 58
  • 73
ErwinM
  • 5,051
  • 2
  • 23
  • 35
  • 2
    is bus a global array? – monkeyStix Jul 25 '16 at 07:02
  • I am not getting exact issue. But let me explain you that by default `enum` first member have value `0` and rest are incremented by `1`. Also `C` does not check array out of bound. – Jayesh Bhoi Jul 25 '16 at 07:06
  • 4
    Make sure you actually put values inside of the element of bus you are later fetching. – Checkmate Jul 25 '16 at 07:08
  • 1
    @Checkmate my thoughts exactly, unless the array is global and then all the array members are initialized to 0 – monkeyStix Jul 25 '16 at 07:11
  • 1
    Enum values are specified by C standard to start at `0` and increment by `1`, Are you sure that you are accessing `bus` directly, instead of a pointer to a larger type somewhere? I.e. `long *b = (long*)bus; b[4]` would obviously be a problem. – vgru Jul 25 '16 at 07:11
  • To single out the actual problem, make a minimal self-contained example and share the complete code of it. It might be related to macros. – Roland Illig Jul 25 '16 at 07:35
  • The fact that enlarging your array makes it work again makes me think that you are not accessing it as an array of short, as @Groo already said. How are you accessing it? – Rudy Velthuis Jul 25 '16 at 07:46
  • oh - how are you outputting the elements of the array to know what you're getting? Maybe it's possible you're using the wrong format specifier? – galois Jul 25 '16 at 08:19

3 Answers3

2

It's hard to tell because you haven't included any relevant code. But here are some ways you could get a wrong value:

  1. You use a pointer of a wrong size and read past the end of the array:

    long* b = (long*)bus;
    result = b[4]; // this will read past the end of the array
    
  2. You copy from other location into the bus array, but use a wrong count:

    short bus[5];
    
    // this is 5
    int count = sizeof(bus)/sizeof(bus[0]);
    
    // this will copy 5 bytes, instead of 5 shorts
    // (this is why bus[10] would fix the issue, for example)
    memcpy(bus, some_location, count);
    
  3. You never initialize the array, but read the value before writing to it:

    // this *doesn't* clear the contents of the array
    short bus[5];
    
    // value of result is undefined
    result = bus[4];
    
vgru
  • 49,838
  • 16
  • 120
  • 201
0

To clarify: When you declare enum bus_sigs { REG0, REGA, REGB, REGC, REGD }; you are basically saying that each of these keywords gets the following assignment within the enum's scope:

int REG0 = 0;
int REGA = 1;
int REGB = 2;
int REGC = 3;
int REGD = 4;

This means that bus[REG0] is equivalent to bus[0]. The issue you're having, then, is mostly likely related to trying to fetch an element of bus that you never declared (which has an undefined value provided that bus is a local variable) or inadvertently changing some element of bus somewhere else in your code (which may give an unexpected result).

Checkmate
  • 1,074
  • 9
  • 16
  • ... or accessing an uninitialized (local) variable. – Rudy Velthuis Jul 25 '16 at 07:35
  • @RudyVelthuis: OP said he is *fetching data from beyond the array memory range*. Whether the actual value of this `float` was initialized is irrelevant in this case. – vgru Jul 25 '16 at 08:12
  • @Groo: he said "**as if** I am fecthing...". Not quite the same, And what float do you mean? – Rudy Velthuis Jul 25 '16 at 08:26
  • @Rudy: sorry, I was looking at a different question at the same time, I meant `short` obviously. But the fact that allocating `10` places seems to fix the issue would make me presume the same thing. – vgru Jul 25 '16 at 09:10
  • @groo If he were actually accessing data from beyond the array memory range by indexing, he wouldn't be able to compile. i.e. trying to index `bus[100]` will give a bounds error... – galois Jul 25 '16 at 09:31
  • @jaska: I am pretty sure C standard doesn't prevent reading past the end of the array. And while you might cause a segfault if your buffer is at an "unfortunate" location, there is also no mechanism in C which will detect "bounds errors". That's why things like [buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) exist. – vgru Jul 25 '16 at 09:47
  • @jaska Yeah, there is no mechanism in C for checking array bounds. See: http://stackoverflow.com/questions/1239938/accessing-an-array-out-of-bounds-gives-no-error-why – Checkmate Jul 25 '16 at 16:37
  • @groo I'm guessing you downvoted. Could you explain why? I answered the OP's question... – Checkmate Jul 25 '16 at 16:38
  • @Checkmate: Hi, no, it wasn't me, I find all answers here helpful. I was downvoted too (I have 2 upvotes and 1 downvote). Same for OP's question, it has 2 upvotes and 1 downvote, so someone was having a bad day I guess. I upvoted you now so you should get +8 rep. – vgru Jul 25 '16 at 16:41
  • @groo Oh, fair enough, sorry about that, I leaped to conclusions. Thanks though, I was worried my answer was wrong somewhere. – Checkmate Jul 25 '16 at 16:46
0

Have you initialized the array yet? Just writing short bus[5]; will allocate the memory for 5 short variables but that's all.

What you can do is short bus[5] = {0}; and it will initialize all entries to 0 so you know exactly what you're dealing with ahead of time.

galois
  • 825
  • 2
  • 11
  • 31
  • OP said he is *fetching data from beyond the array memory range*. Setting values to zero cannot influence that in any way. – vgru Jul 25 '16 at 08:12
  • See my other comment: "... **as if** I am fecthing...". – Rudy Velthuis Jul 25 '16 at 08:28
  • @jaska If I initialize `bus` like you propose it solves the problem. To make sure I understand what happened here: if I allocate memory `short bus[5]` and then do f.e. `bus[3] = 5` that will not actually put the value in the 4th memory location? – ErwinM Jul 25 '16 at 08:31
  • @ErwinM: it's impossible to say without looking at your exact code. If you never initialize your values, they will be random like this answer suggests. But `bus[3] = 5` *will* set the correct value in both cases, and it will be `5` afterwards; the only question is whether you expect it to be `0` *before* you touch it for the first time. Edit your question to include some functions where you write and read to these locations. – vgru Jul 25 '16 at 09:14
  • I should note I haven't been able to reproduce the error in a few cases (changing global/locality of enum and array, assigning wrong types, etc). But yeah, the idea is that before you actually initialize anything the data in the array isn't guaranteed to be empty, so you're going to see "strange" values (of the same type that the array is supposed to hold) if you try to access it. – galois Jul 25 '16 at 09:30