LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Dereference of out-of-bounds pointer: 1 bytes (1 elements) past end of array.

I have a function which modifies individual bytes inside of other data types.  (ie: looking at the high or low byte of a larger value)  The function takes the address as a parameter of "void *" and then casts it to a local pointer of the desired type, such as "unsigned char".  This works fine for the byte I'm pointing to directly, but if I try to reference subsequent bytes I get a Run Time Error complaining about the array index being out of bounds.  I have used this technique in Microsoft C, and other compilers, without problems, and I have taken my exact CVI function and placed it in Visual C and it works properly.  I can see the addresses in the debugger, and they are all pointing to the correct places, so the pointer math is correct, still the program won't execute it.

 

1: Is there a  different way to express this which the run time system will accept?

2: Is there a way to turn off the run time checking of array boundries?

 

Here's some sample code, which functions properly in MS C, but not in CVI:

 

void PutWordVal(void * y, WORD x)
{
BYTE * a;    

    a = (BYTE*)y;                        //Convert pointer type
    *a++ = (BYTE)((x >> 😎 & 0xff);      //Save high order first
    *a = (BYTE)(x & 0xff);               //Save low order in next address (FAILS HERE)
}

This function fails writing the 2nd byte.  I've tried it using various different formats, and doing the pointer math differently, all with the same result. Any ideas??

 

(Using Version 13.0.0 (632)

0 Kudos
Message 1 of 9
(9,252 Views)

This seems to be working :

#define WORD unsigned long
#define BYTE unsigned char

void PutWordVal(void * y, WORD x);

// Main ===============================
int main (void)
{
	int MyInteger = 0;
	int* MyIntPointer = &MyInteger;
	
	PutWordVal (MyIntPointer, 1234);
	
	return 0;
}

// PutWordVal function ===============================
void PutWordVal(void * y, WORD x)
{
BYTE* a[2];

    a[0] = (BYTE*)y;                               //Convert pointer type
    a[1] = (BYTE*)y + 1;
	
    *a[1] = (BYTE)((x >> 8) & 0xff);        //Save high order first 
    *a[0] = (BYTE)(x & 0xff);                  //Save low order in next address (FAILS HERE)
}

 

I'm using a 2-item array in order to allocate 2 bytes of memory before executing the first instruction of the subfunction. In your example, a++ memory address is dereferenced with * before being initialized.

 

Is it what you need ?

0 Kudos
Message 2 of 9
(9,223 Views)

Here is a screenshot with breakpoints...

 

The value tested is "1234" which binary notation is : 0100 1101 0010

 

So we can see that :

- 0100 -> decimal value is "4"

- 11010010 -> decimal value is "210"

 

 

Screenshot.JPG

0 Kudos
Message 3 of 9
(9,219 Views)

What you are doing is a bit different.  You have an array of pointers.  I have a pointer to an unknown section of memory which I want to address as bytes regardless of what's here.  The idea is to able to reference the individual bytes which make up a larger data type.  In this way I can gaurantee the order of the bytes in memory and swap things around elsewhere in my code.  This works very well in Microsoft C, where I've tested and used it many times.  Also, you've said that I used *a before initializing it, but that is not true!  It is initialized in the previous line to point to the first byte of a 2 byte word variable.  The "++" points it to the second byte of the word so that the succeeding line moves its data to the next memory location in order.

 

I have found where the problem is.  The error message was misleading, saying that I was indexing an array out of bounds.  That's not what was happening.  The run-time error check was happy to let me move data around and alter my pointer, as long as it did not go out of the boundry of a single elemental variable.  I was referencing a union where data type at the address pointed to could change, and depending on what was there at the time it would work or fail.  This was not obvious since the reference to the variable causing the problem was several indirections away and I didn't see it.  Microsoft apparently does not boundry check in this way, and the exact same code functioned perfectly.  Here, it saw I went outside the elemental variable, and even though I was still inside the same named union, it tripped a run-time error (which in turn tripped my headache 😉

 

Thanks for the input,

Mike

0 Kudos
Message 4 of 9
(9,200 Views)

You're right. I said a bull**bleep** when I wrote that the pointer was not initialized. Sorry about that ! ^^

 

I don't really understand what your problem was. Can you just give an example and show a piece of code please ? (I'm interested by the way you fixed your problem)

0 Kudos
Message 5 of 9
(9,184 Views)

Hi Rallyr,

 

You're code is working without ant error in CVI 2012 when I apply the function to a static byte array ( PutWordVal(myByteArray,myWord);) , if your array is dynamically allocated have you tried to disable pointer protection (search DISABLE_RUNTIME_CHECKING in CVI help) on 'a' pointer. If it is due to pointer protection your application should work properly in release mode and show an error only in debug mode.

 

regards,

Stephane

Labwindows/CVI user since version 4.0
0 Kudos
Message 6 of 9
(9,170 Views)

The CVI 2013 system seems to be quite different from the 2012. (for example, you can't compile a project on a network drive!) I had no problem if the destination data was an actual dimensioned array.  The trouble occured when the pointer actually pointed to a different data type.  Even though I cast it to the type I want, the run time system still thought I was pointing to an array, and thus the confusing out of bounds error.  I've changed my data structures and code to accomodate the compiler, and moved on.  I don't know that this problem rises to the level of a bug, but it's certainly something which works differently from other complilers and run-time systems.

 

Thank you all for your input.  I'm onto greener pastures and new challenges!

 

Mike

Message 7 of 9
(9,163 Views)

I had similar problems in DEBUG configuration ONLY. CVI debugger gives (misleading?) "Dereference of out-of-bounds pointer" in situations where everything looks fine, or at least it's difficult to understand what the issue refers to.

So I had to disable "run-time check" in Debug build configuration to move on (Release build works fine).

I'm using CVI 2017 so it looks like this issue remains for several versions. NI should do/tell something about this because it's very frustrating and time consuming.

0 Kudos
Message 8 of 9
(5,289 Views)

The issue stems from the fact that the CVI checker in this case relies on static type information inferred from the source code rather than effective runtime information about the pointers passed into. Most likely this is a problem that entered LabWindows/CVI when they switched the compiler backend from their own custom C compiler to the standard open source LLVM compiler framework.

A void* pointer is void (sic) of all type information and hence a static code checker can not infer anymore what is a safe access on such a pointer. A dynamic code checker requires quite complex runtime type information stored with every single pointer and that can add up to a significant resource hog so that it is not a good idea to apply that as a blanket solution everywhere. Making it a choice has the problem of safely storing if this information is available or not for a particular pointer and complicates the dynamic typedef meta data to maintain for every pointer even more as well as posing the problem of having to develop a smart decider that can make this choice, with the problem that this decision can be wrong on occasion.

The old custom made C compiler was much more integrated with the code analyzer and debugger and let the debugger have much easier access to internal compiler data at runtime. With the standardization on LLVM some of this has been lost.

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 9
(5,251 Views)