正如你们中的一些人所知,微软已经取消memcpy()了安全开发生命周期,取而代之的是memcpy_s().
void *memcpy(void *dest, const void *src, size_t n);
/* simplified signature */
errno_t memcpy_s(void *dst, size_t dstsize, const void *src, size_t n);
Run Code Online (Sandbox Code Playgroud)
因此,如果您的代码曾经是:
if (in_len > dst_len) {
/* error */
}
memcpy(dst, src, in_len);
Run Code Online (Sandbox Code Playgroud)
它成为了:
if (memcpy_s(dst, dst_len, src, src_len)) {
/* error */
}
Run Code Online (Sandbox Code Playgroud)
或者,截断,
memcpy(dst, src, min(in_len, dst_len));
Run Code Online (Sandbox Code Playgroud)
VS
(void)memcpy_s(dst, dst_len, src, src_len);
Run Code Online (Sandbox Code Playgroud)
问题:额外长度参数如何使代码更安全?要使用memcpy(),我应该已知所有四个参数,并将适当的长度作为第三个参数传递.什么阻止我犯错误计算目标缓冲区大小并传递错误的价值dst_size?我不明白为什么它memcpy()与它有任何不同以及它被弃用的原因.有没有我看不到的常见用例?我在这里错过了什么?
我确实知道is_pod一个类型的充分条件是memcpy可行的,但has_trivial_destructor 也足够用于此目的?如果没有,为什么?
我总是被告知(在书籍和教程中),在将数据从内核空间复制到用户空间时,我们应该使用copy_to_user()并使用memcpy()会给系统带来问题.最近我错误地使用了memcpy(),它完全没有任何问题.为什么我们应该使用copy_to_user而不是memcpy()
我的测试代码(内核模块)是这样的:
static ssize_t test_read(struct file *file, char __user * buf,
size_t len, loff_t * offset)
{
char ani[100];
if (!*offset) {
memset(ani, 'A', 100);
if (memcpy(buf, ani, 100))
return -EFAULT;
*offset = 100;
return *offset;
}
return 0;
}
struct file_operations test_fops = {
.owner = THIS_MODULE,
.read = test_read,
};
static int __init my_module_init(void)
{
struct proc_dir_entry *entry;
printk("We are testing now!!\n");
entry = create_proc_entry("test", S_IFREG | S_IRUGO, NULL);
if (!entry)
printk("Failed to creats proc entry test\n"); …Run Code Online (Sandbox Code Playgroud) 起初我有这个简单的protobuf文件
message messagetest
{
...
repeated float samples = 6;
....
}
Run Code Online (Sandbox Code Playgroud)
这使用此方法创建头文件
//repeated float samples = 6;
inline int samples_size() const;
inline void clear_samples();
static const int kSamplesFieldNumber = 6;
inline float samples(int index) const;
inline void set_samples(int index, float value);
inline void add_samples(float value);
inline const ::google::protobuf::RepeatedField< float >& samples() const;
inline ::google::protobuf::RepeatedField< float >* mutable_samples();
Run Code Online (Sandbox Code Playgroud)
我基本上做的是在for循环中逐个复制所有数据.
int main(int argc, char** argv)
{
messagetest fMessage;
vector<float> fData (1000, 0);
// Create 1000 random values
for (int i = …Run Code Online (Sandbox Code Playgroud) 我在将微控制器上的一些数据从一个结构复制到另一个结构时遇到了硬错误异常.我尝试了不同的实现,它们应该完全相同.看我的代码行:
memcpy(&msg.data, data, 8);
memcpy(&msg.data, data, sizeof(*data));
memcpy(&msg.data, data, sizeof(msg.data));
msg.data = *data; // Hard Fault
Run Code Online (Sandbox Code Playgroud)
前三行工作得很好.最后一个以硬故障异常结束.线的组装memcpy是相同的.直接分配的程序集有所不同:
memcpy(&msg.data, data, sizeof(msg.data));
800c480: f107 030c add.w r3, r7, #12
800c484: 330b adds r3, #11
800c486: 2208 movs r2, #8
800c488: 6879 ldr r1, [r7, #4]
800c48a: 4618 mov r0, r3
800c48c: f7f4 f82e bl 80004ec <memcpy>
msg.data = *data; // Hard Fault
800c490: 687b ldr r3, [r7, #4]
800c492: f107 0217 add.w r2, r7, #23
800c496: cb03 ldmia r3!, {r0, …Run Code Online (Sandbox Code Playgroud) 这是代码:
unsigned int a; // a is indeterminate
unsigned long long b = 1; // b is initialized to 1
std::memcpy(&a, &b, sizeof(unsigned int));
unsigned int c = a; // Is this not undefined behavior? (Implementation-defined behavior?)
Run Code Online (Sandbox Code Playgroud)
a该标准是否保证在我们进行初始化的地方是一个确定的值c?Cppreference说:
void* memcpy( void* dest, const void* src, std::size_t count );将
count字节从指向的对象复制到src指向的对象dest。这两个对象都重新解释为的数组unsigned char。
但是我看不到cppreference中的任何地方,如果说这样不确定的值被“复制到”,它将变成确定的。
从标准看来,这类似于:
unsigned int a; // a is indeterminate
unsigned long long b = 1; // b …Run Code Online (Sandbox Code Playgroud) 我试图将包含int,char和char数组的结构的成员复制到字节数组中以发送到串行线.到目前为止我有
struct msg_on_send
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};
void switch_output_on()
{
int member;
struct msg_on_send SendMsg_on[sizeof member] =
{
};
unsigned char buffer [ sizeof SendMsg_on[0] ];
showbytes(buffer, serialize(buffer, SendMsg_on));
}
/***************************************************************************
* Function: ArrayBuild *
* Purpose: Uses memcopy to transfer the struct members sequentially *
* into an array of char *
* Arguments: *
* Returns: size_t i = a count of the number of bytes in the …Run Code Online (Sandbox Code Playgroud) 我是C新手,但多年来一直是程序员,所以我试图从2008年开始沿着斯坦福大学的课程学习C,并在C.中的向量上做作业3.
它基本上只是一个通用数组,所以数据作为一个结构保存在一个结构中void *.编译器标志-Wpointer-arith打开,所以我不能算术(我明白原因).
数据周围的结构必须不知道数据的类型,因此它对调用者来说是通用的.
为简化起见,我正在尝试以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
void *data;
int aindex;
int elemSize;
} trial;
void init(trial *vector, int elemSize)
{
vector->aindex = 0;
vector->elemSize = elemSize;
vector->data = malloc(10 * elemSize);
}
void add(trial *vector, const void *elemAddr)
{
if (vector->aindex != 0)
vector->data = (char *)vector->data + vector->elemSize;
vector->aindex++;
memcpy(vector->data, elemAddr, sizeof(int));
}
int main()
{
trial vector;
init(&vector, sizeof(int));
for …Run Code Online (Sandbox Code Playgroud) memcpyC17 关于[7.24.2.1p2]做了以下说明:
memcpy 函数将 s2 指向的对象中的 n 个字符复制到 s1 指向的对象中。如果复制发生在重叠的对象之间,则行为未定义。
常见的解释是您不能复制重叠的内存区域。但这并不完全相同,因为同一对象中可能存在不重叠的区域。
想象一下一个典型的实现,其中sizeof(unsigned int) == 4和sizeof(unsigned short) == 2。为了简单起见,进一步假设没有陷阱表示,并且alignof(unsigned short) <= alignof(unsigned int)。考虑:
unsigned int x = 0xdeadbeef;
unsigned short *p = (unsigned short *)&x;
memcpy(&x, p+1, 2);
Run Code Online (Sandbox Code Playgroud)
解释#1:我在x和 之间复制x,对象x当然与自身重叠,所以我导致了 UB。
解释#2:由于<string.h>函数操作“被视为字符类型数组的对象”[7.24.1p1],因此我实际上将其视为x数组unsigned char[4],并且我只是将该数组的元素 2 和 3 复制到元素 0 和 1。这些unsigned char对象不以任何方式重叠,所以我没有造成UB。我得到了和我一样的效果unsigned char *q = (unsigned char *)&x; …