1

I am trying to use memcpy to pick out a specific range of data which I am interested, like using the syntax from Matlab array(100:200). However, when I tried to print out the result to check if the function did right or not, I got an error: Exception thrown at 0x00007FFF4A921399 (vcruntime140d.dll) in Examplefordebug.exe: 0xC0000005: Access violation writing location 0x0000000000000000. Any thought to solve this problem? The result suppose to be two 5 from the array ch2Buffer

Here is the example code:

#include <iostream>
#include <stdio.h>
#include <string.h>

int main()
{
    int i,n;
    const int u32Size = 10;
    float* ch1Buffer = NULL;
    double* ch2Buffer = NULL;
    double* ch2newBuffer = NULL;
    
    int pBuffer[u32Size] = {10,2,10,2,10,5,10,5,10,2};
    int* pi16Buffer = pBuffer;

    ch1Buffer = (float*)calloc(u32Size, sizeof* ch1Buffer);
    ch2Buffer = (double*)calloc(u32Size, sizeof* ch2Buffer);
    

    // De-interveal the data to ch1Buffer and ch2Buffer
    for (i = 0; i < u32Size/2; i++)
    {
        ch1Buffer[i] += pi16Buffer[i * 2];
        ch2Buffer[i] += pi16Buffer[i * 2 + 1];
    }

    // Use memcpy to pick out the data we are interested
    memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));



    // Print out to check the result
    for (i = 0; i < 3; i++) {
        printf("%f ", ch2newBuffer[i]);
    }

    free(ch1Buffer);
    free(ch2Buffer);
    return 0;
}
Kevin
  • 121
  • 8
  • ``memcpy(ch2newBuffer,`` – you are copying into a pointer variable that is NULL as the destination has never been allocated. Therefore you get a NULL pointer dereference. – phg Dec 22 '20 at 14:10
  • So do you mean the `ch2newBuffer` have to be declared to other format? – Kevin Dec 22 '20 at 15:08

1 Answers1

2

"Access violation writing location 0x0000000000000000. Any thought to solve this problem?"

Yes, your code is attempting to write to a memory location for which the process does not yet own...
You have a declaration here:

double* ch2newBuffer = NULL;

Then an attempt to copy an object to it:

memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));

Without allocating memory first. Allocating memory will address the problem.

Add a 3rd memory allocation, and check the result of each before attempting to use the buffer. Some additional suggestions, don't cast the return of (m)(c)(re)alloc() in C, and do not use memory created with [m][c][re]alloc() without first verifying that the call was successful. Here is a refactored section including these suggestions:

ch1Buffer = calloc(u32Size, sizeof* ch1Buffer);
if(ch1Buffer)
{
    ch2Buffer = calloc(u32Size, sizeof* ch2Buffer);
    if(ch2Buffer)
    {
        ch2newBuffer = calloc(u32Size, sizeof* ch2Buffer);
        if(ch2newBuffer)
        {
            // De-interveal the data to ch1Buffer and ch2Buffer
            for (i = 0; i < u32Size/2; i++)
            {
                ch1Buffer[i] += pi16Buffer[i * 2];
                ch2Buffer[i] += pi16Buffer[i * 2 + 1];
            }

            // Use memcpy to pick out the data we are interested
            memcpy(ch2newBuffer, &ch2Buffer[2], 2 * sizeof(ch2Buffer[0]));



            // Print out to check the result
            for (i = 0; i < 3; i++) {
                printf("%f ", ch2newBuffer[i]);
            }
            free(ch2newBuffer); 
        }else {/*handle error*/}
        free(ch2Buffer);
    }else {/*handle error*/}
    free(ch1Buffer);
}else {/*handle error*/}

One additional potential issue... Depending on your compiler, you may have registered an additional error here:

 const int u32Size = 10;
 ...
 int pBuffer[u32Size] = {10,2,10,2,10,5,10,5,10,2};

A variable sized object VLA (defined in C99, and optionally in compilers since then.) may not be initialized at declaration. (read more about this here)

Declaration can be done as following for a non-VLA array with initializer can be in several forms:

#define U32_SIZE 10

 int pBuffer[10] = {10,2,10,2,10,5,10,5,10,2};
 int pBuffer[U32_SIZE] = {10,2,10,2,10,5,10,5,10,2};
 int pBuffer[] = {10,2,10,2,10,5,10,5,10,2};

Or the following for a VLA (which cannot be initialized, and can only be declared within automatic scope.)

 int iBuffer[] = {10,2,10,2,10,5,10,5,10,2};//non-VLA for illustration
 int pBuffer[u32Size];//VLA 
 memcpy(pBuffer, iBuffer, sizeof(iBuffer);//update VLA with contents of iBuffer.
 
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Hi thanks for point out. I tried the last part you wrote, but the problem didn't get solve – Kevin Dec 22 '20 at 15:07
  • @Kevin - did you do what I suggested to do? (_" Allocating memory will address the problem."_. When I ran your code after allocating memory ( `ch2newBuffer = calloc(u32Size, sizeof* ch2Buffer);` ) it worked just fine. i.e. the error you asked for help on is no longer there. Do you have another problem you are speaking of? – ryyker Dec 22 '20 at 15:12
  • 1
    Sorry about that, I didn't figure out it. Yes! it works! – Kevin Dec 22 '20 at 15:31