尝试从常量 char * 类型的指针复制数据时出现“超出内存访问”错误。为啥?
Posted
技术标签:
【中文标题】尝试从常量 char * 类型的指针复制数据时出现“超出内存访问”错误。为啥?【英文标题】:Getting "accessing beyond memory" error when it is tried to copy data from a pointer of type constant char *. Why?尝试从常量 char * 类型的指针复制数据时出现“超出内存访问”错误。为什么? 【发布时间】:2014-03-31 10:41:20 【问题描述】:以下语句引发超出内存错误的访问。我仍然不确定它为什么会那样做。谁能帮我在这里做错了什么?谢谢
memcpy(mhp_ptr->dpair[0].dpairid, id0, 8);
这里 id0 的类型是 const char *
其中,mhp_ptr 是 mhp_t * 类型,其定义如下:-
typedef struct mhp_s
uint8_t editor[16];
uint64_t refcode;
uint64_t error_id;
union
uint8_t dpairtbl[16][6];
dpairtbl_t dpair[6];
;
mhp_t;
而dpairtbl_t定义如下:-
typedef struct dpairtbl_s
char dpairid[8];
uint64_t dpairdata;
dpairtbl_t;
错误:- 访问超出分配的内存 “memcpy”可以从缓冲区“id0”中读取 8 个字节
我的项目的编译器设置将警告视为错误。正常编译工作正常,但它发出一个警告,根据我的编译器中的设置被视为错误。 只是想知道为什么它对 strcpy 工作正常,但在 memcpy 的情况下发出警告。在字符串的情况下,对 memcpy 的使用是否有任何 C++ 限制?
【问题讨论】:
嗯,id0
指向的内存是多少?
您将 8 个字符的大小 + 一个 int64 写入包含 8 个字符的内存中。
id0 是 const char* 类型。如果我使用 strcpy 它可以正常工作,我不会收到任何错误,但如果我使用 memcpy 它会引发错误
【参考方案1】:
将memcpy
视为内存中字节的复制:
memcpy(mhp_ptr->dpair[0].dpairid, id0, 8);
如果id0
的长度小于8,memcpy
也会复制不属于你的内存,如果是8个或更多字符,dpairid
不会为null-正确终止。
如果您无法保证 id0
的大小正好是 8 个字节,则应将其视为字符串,以便根据终止字符确定长度:
strncpy (mhp_ptr->dpair[0].dpairid, id0, 7);
mhp_ptr->dpair[0].dpairid[7] = '\0';
【讨论】:
即使我使用 8 而不是 sizeof(dpairtbl_t) 也会引发错误,抱歉编辑了问题以避免混淆 @user3480704:告诉我们id0
是如何定义和初始化的。
@user3480704 然后我们回到 id0 中有什么的问题
id0 被定义为 const char * id0 作为功能参数之一。它基本上包含提供错误信息的字符串。【参考方案2】:
一个潜在的问题是您正在复制到 dpairid(大小为 8),大小为 dpairtbl_t(可能为 16)
要么你的尺寸有误(使用 sizeof(dpairid)),要么
typedef struct dpairtbl_u
char dpairid[8];
uint64_t dpairdata;
dpairtbl_t;
应该是联合
typedef union dpairtbl_u
char dpairid[8];
uint64_t dpairdata;
dpairtbl_t;
【讨论】:
它只是 struct 类型,如果我使用 strcpy,它可以正常工作,但在 memcpy 的情况下会引发错误。抱歉造成混淆,编辑问题以进一步澄清 @user3480704 with strcpy 如果 id0 的长度小于 8,它将起作用,因为 strcpy 在找到字符串末尾的 '\0' 时停止。 是的,这正是为什么对于任何未来与字符串相关的操作,我想知道 memcpy 是否是正确的前进方式 如果可以,请使用 std::string ...要复制的字符数(以免超出目标缓冲区)。【参考方案3】:除了其他答案之外,我没有收到任何错误并且它有效。这是我的代码:
const char* id0 = "*** question";
mhp_t* mhp_ptr = new mhp_t;
memcpy(mhp_ptr->dpair[0].dpairid, id0, sizeof(dpairtbl_t));
cout << mhp_ptr->dpair[0].dpairid << endl;
delete mhp_ptr;
输出是:
stackove
当我查看sizeof(dpairtbl_t)
值时,它是8
。也许您忘记了指针mhp_ptr
的分配/初始化。以及如何初始化id0
?
【讨论】:
id0 作为字符串传递。正常编译工作正常,但它发出一个警告,根据我的编译器中的设置被视为错误。只是想知道为什么它对 strcpy 工作正常但在 memcpy 的情况下发出警告。有C++限制吗?以上是关于尝试从常量 char * 类型的指针复制数据时出现“超出内存访问”错误。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用指向 char* 的指针时出现总线错误 10 或分段错误 11,具体取决于封装
尝试使用 pyspark 从 S3 获取数据时出现空指针异常