Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#

后端 未结 3 1373
一个人的身影
一个人的身影 2021-02-07 18:33

I have a c++ dll which serving some functionality to my main c# application. Here i try to read a file, load it to memory and then return some information such as the Pointer to

相关标签:
3条回答
  • 2021-02-07 18:51

    I'm late to the party but here I go.

    I received this error code from my own program, which brought me to this post. I was setting an array position out of range, causing the next allocation to crash the program, in Windows 7. I found the error by compiling with the -g flag with gcc from MinGW and then running the program with gdb. Somewhere here you read or write an invalid location and the next allocation picks up on the heap corruption. I solved my problem by bounds checking my iterators, but that doesn't seem to be the problem here.

    Main Problems with the C Program:

    • The method you are using to find the size of the file is alright, however when you allocate memory for the Data array you are casting to a 32 bit integer array, which has problems. Casting to this requires that the size of the file in bytes be some multiple of 4. If you were to have a file with FILE_SIZE % 4 == 1 then there are 3 bytes which are not part of your allocated data, but are accessed when you look at the final element of the u32 array.
    • How fread is implemented, you should be protected from writing to this out of range position, however you will miss the last 1 to 3 characters when the file size is not a multiple of 4 since integer division truncates remainders.
    • You should close the file before exiting the scope, including after reading everything in the file.

    Solutions:

    • A solution to this is may be to round up the array size to the nearest multiple of 4. You are then guaranteed to not access out of range positions from [0] to [fSize - 1].
    • If trying to copy past the last byte of the file causes a fatal error I don't have a decent solution besides using character arrays rounded up the nearest multiple of 4, then reading byte for byte. After reading everything you can then cast to u32 since C is permissive with casting.

    That version of software may have been doing some extra work when casting so that it wrote to a location out of range, or C# made some extra allocation calls that would do the same (I am not familiar with how C# compiles and what instruction changes it may impose).

    Some code for finding the next multiple of 4:

    size_t diff, rfSize = fSize; /* size_t is preferable for array sizes and indexes, 
                                  * but matching to fSize's data type will work and
                                  * ensures no truncation occurs. */
    
    /* Only if this is not already a multiple of 4 */
    if (diff = fSize % 4)
      /* Mod gives the remainder by division by 4, which is also the difference between 
       * fSize and the next multiple of 4. */
      rfSize= fSize + diff;
    
    0 讨论(0)
  • 2021-02-07 19:06

    If all your code is indeed what is shown above, then I don't see the problem. However, when I get this issue, sometimes its because malloc/new/whatever detects heap corruption, often this corruption has already occurred previously in the program, but the crash has been delayed until the next call to new/malloc.

    If you read other files, or allocate or free other buffers before the above is executed and crashes, I would look there for problems. Perhaps throw a bunch of asserts anywhere you write to buffers and check the bounds and what you are writing for overruns. Sorry this isn't a concrete answer, I do not have enough rep to leave this advice as a comment.

    0 讨论(0)
  • 2021-02-07 19:16

    You are allocating the output data 2 times. Once in C# as new IntPtr and then in C++ as GlobalAlloc and then return the Pointer Returned by GlobalAlloc. So the Pointer returned by new intPtr has been lost.

    0 讨论(0)
提交回复
热议问题