【问题标题】:Problem to print out the result from memcpy从 memcpy 打印结果的问题
【发布时间】:2020-12-22 14:06:15
【问题描述】:

我正在尝试使用memcpy 来挑选我感兴趣的特定数据范围,例如使用Matlab array(100:200) 中的语法。但是,当我尝试打印结果以检查功能是否正确时,出现错误:Exception thrown at 0x00007FFF4A921399 (vcruntime140d.dll) in Examplefordebug.exe: 0xC0000005: Access violation writing location 0x0000000000000000. 有没有想过解决这个问题?结果假设是数组ch2Buffer中的两个5

示例代码如下:

#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;
}

【问题讨论】:

  • memcpy(ch2newBuffer, - 您正在复制到一个为 NULL 的指针变量,因为目标从未被分配。因此你会得到一个 NULL 指针解引用。
  • 那么您的意思是ch2newBuffer 必须声明为其他格式吗?

标签: arrays c sorting printf memcpy


【解决方案1】:

“访问冲突写入位置 0x0000000000000000。有解决这个问题的想法吗?”

是的,您的代码正在尝试写入进程尚未拥有的内存位置...
你在这里有一个声明:

double* ch2newBuffer = NULL;

然后尝试将一个对象复制到它:

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

没有先分配内存。分配内存将解决问题。

添加第三个内存分配,并在尝试使用缓冲区之前检查每个结果。一些额外的建议,don't cast the return of (m)(c)(re)alloc() in C,并且在没有首先验证调用是否成功之前不要使用[m][c][re]alloc() 创建的内存。这是包含这些建议的重构部分:

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*/}

一个额外的潜在问题...根据您的编译器,您可能在此处注册了一个额外的错误:

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

可变大小的对象VLA(在 C99 中定义,此后在编译器中定义。)可能不会在声明时初始化。 (read more about this here)

对于带有初始化器的非 VLA 数组,可以如下声明:

#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};

或以下用于 VLA(无法初始化,只能在自动范围内声明。)

 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.
 

【讨论】:

  • 您好,感谢您的指出。我试过你写的最后一部分,但问题没有得到解决
  • @Kevin - 你按照我的建议去做了吗? (“分配内存将解决问题。”。当我在分配内存(ch2newBuffer = calloc(u32Size, sizeof* ch2Buffer);)后运行您的代码时,它工作得很好。即您寻求帮助的错误不再存在。做您还有其他问题吗?
  • 抱歉,我没弄明白。是的!它有效!
猜你喜欢
  • 1970-01-01
  • 2019-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多