使用 memcpy 时出错:“访问冲突读取位置 0x0000000000000000”

Posted

技术标签:

【中文标题】使用 memcpy 时出错:“访问冲突读取位置 0x0000000000000000”【英文标题】:Error using memcpy : "Access violation reading location 0x0000000000000000" 【发布时间】:2022-01-15 08:19:24 【问题描述】:

我正在尝试编写类似于std::vector 的东西,但在 c 中存储一堆数学向量。

这里是包含错误的行。

pVl->pData = memcpy(pNewData, pVl->pData, sizeof(pVl->pData));

我的意图:将数据从pVl->pData 复制到pNewData。然后赋值返回值,也就是 指向新复制的数据存储器开始的指针并将其分配给pVl->pData。我不确定我做错了什么。

MRE:

#include <stdlib.h>
#include <string.h>

typedef enum R_Code  R_OK, R_WARNING, R_FAIL, R_FATAL  R_Code;

struct Vector2_s

    float x;
    float y;
 const Default_Vector2 =  0.0f, 0.0f ;

typedef struct Vector2_s Vector2;

struct Vector2List_s

    //current capacity of the List
    size_t capacity;

    //current size of the list 
    size_t size;

    //data buffer 
    Vector2* pData;

 const Default_Vector2List =  0, 0, NULL ;

typedef struct Vector2List_s Vector2List;

R_Code Vector2List_ReAllocateMem(Vector2List* pVl) 
    if (pVl->capacity == 0) 
        pVl->capacity++;
    

    Vector2* pNewData = malloc(pVl->capacity * 2 * sizeof(Vector2));
    if (pNewData == NULL) 
        return R_FAIL;
    

    pVl->capacity *= 2;
    pVl->pData = memcpy(pNewData, pVl->pData, sizeof(pVl->pData));//EXPECTION THROWN IN THIS LINE
    free(pNewData);
    return R_OK;


R_Code Vector2List_PushBack(Vector2List* pVl, const Vector2 v) 
    if (pVl->size == pVl->capacity) 
        R_Code rcode = Vector2List_ReAllocateMem(pVl);
        if (rcode == R_FAIL) 
            return rcode;
        
    

    pVl->pData[pVl->size] = v; 
    pVl->size++;
    return R_OK;


int main() 

    Vector2List vl = Default_Vector2List;
    Vector2List_PushBack(&vl, Default_Vector2);
    return 0;

【问题讨论】:

抱歉,这是第一个 好像分配失败了。检查分配的大小。 pVl-&gt;pData = memcpy(pNewData, pVl-&gt;pData, sizeof(pVl-&gt;pData)); 你不需要重新分配,你的sizeof 操作数也是错误的。 该消息告诉您从NULL 指针读取。 pvpv-&gt;dataNULL 是的,确实如此。但在下一行中,您将该地址放入free,即新分配的内存。这两个变量在这一行之后包含相同的地址,但块只分配一次。如果通过一个指针释放该块,则不能再取消引用指向同一地址的所有其他指针。 【参考方案1】:

在函数Vector2List_ReAllocateMem 中,您动态分配了内存

Vector2* pNewData = malloc(pVl->capacity * 2 * sizeof(Vector2));

然后在这个语句中

pVl->pData = memcpy(pNewData, pVl->pData, sizeof(pVl->pData));

您正在使用空指针 pVl-&gt;pData 作为调用未定义行为的数据源。

此外,您释放了分配的内存。

free(pNewData);

同样使用sizeof(pVl-&gt;pData)这个表达式没有意义。

看来你需要的是以下

pVl->pData = pNewData;

虽然如果您要重新分配内存,那么您需要使用 malloc 而不是 realloc

你需要完全重写函数。

【讨论】:

我应该用什么来代替sizeof(pVl-&gt;pData)?或者pV1-&gt;pData的大小是多少? @Cool_Cornflakes 您的工作是跟踪之前为pVl-&gt;pData 分配的大小。您不能仅从指针中检索它。 @Gerhardh 等等,我确实有一个大小变量。我会用那个代替吗?如果 size 是数组中元素的数量? @Cool_Cornflakes 你不需要元素的数量,而是字节的数量。如果您可以从您的size 获得此信息,例如pVl-&gt;capacity * 2 * &lt;xy&gt; 那就去吧。顺便说一句:你知道realloc 吗?可能更适合你。 @Cool_Cornflakes 指针声明为 Vector2* pData;。所以你需要分配 Vector2 类型的对象。所以使用 sizeof( Vector2 )

以上是关于使用 memcpy 时出错:“访问冲突读取位置 0x0000000000000000”的主要内容,如果未能解决你的问题,请参考以下文章

memcpy() 给我段错误

浅析在类模版中构建成员函数时,使用memcpy产生的副作用

使用 gcc 编译器时未在此范围内声明“memcpy”

在 mmap'ed 区域崩溃时使用 memcpy,for 循环不会

c语言中strcpy跟mencpy哪个效率更高?

STM32对memcpy的调用导致hardfault(对memcpy本身的调用,而不是memcpy的执行)