跳转至

C语言内存函数详解:memcpy、memmove、memset与memcmp使用指南

原文地址: https://88box.top 生成时间: 2026-05-21 01:00:56


C语言内存函数 - hey99 知识搜索引擎

精选文章

C语言内存函数

C语言内存函数

更新于 2026-05-20 16:57

restful

c语言

后端

开发语言

目录

  1. memcpy

1.1 代码演示

1.2 模拟实现

  1. memmove

2.1 代码演示

2.2 模拟实现

  1. memset

3.1 代码演示

3.2 总结

  1. memcmp

4.1 代码演示

4.2 总结

  1. memcpy

项目

内容

函数名

memcpy

头文件

include

函数原型

void memcpy(void destination, const void *source, size_t num);

功能

source

指向的内存位置开始,复制

num

个字节的数据到

destination

指向的内存位置

参数

destination

目标空间地址,拷贝后的数据存放到这里

参数

source

源空间地址,要被拷贝的数据从这里开始

参数

num

要拷贝的数据字节数

返回值

返回目标空间的起始地址,即

destination

注意事项

memcpy

只负责按字节拷贝内存

不关心数据类型

限制条件

如果

source

destination

指向的内存区域发生重叠,结果是

未定义的

1.1 代码演示

字符拷贝:

define

_CRT_SECURE_NO_WARNINGS

1

include

include

int

main

(

)

{

char

arr

[

20

]

=

{

0

}

;

char

arr1

[

]

=

"abcdef"

;

memcpy

(

arr

,

arr1

,

6

)

;

printf

(

"%s\n"

,

arr1

)

;

//abcdef

return

0

;

}

数字拷贝

int

main

(

)

{

int

arr1

[

10

]

=

{

0

}

;

int

arr2

[

]

=

{

1

,

2

,

3

,

4

,

5

,

6

,

7

,

8

,

9

,

10

}

;

int

sz

=

sizeof

(

arr2

)

/

sizeof

(

arr2

[

0

]

)

;

memcpy

(

arr1

,

arr2

,

sz

*

4

)

;

for

(

int

i

=

0

;

i

<

sz

;

i

++

)

printf

(

"%d "

,

arr1

[

i

]

)

;

// 1 2 3 4 5 6 7 8 9 10

return

0

;

}

画图演示:

注意:在拷贝中可能会出现重叠的情况,如下:

int

main

(

)

{

int

arr1

[

10

]

=

{

0

}

;

int

arr2

[

]

=

{

1

,

2

,

3

,

4

,

5

,

6

,

7

,

8

,

9

,

10

}

;

int

sz

=

sizeof

(

arr2

)

/

sizeof

(

arr2

[

0

]

)

;

memcpy

(

arr2

,

arr2

+

2

,

20

)

;

//源:arr2[2] ~ arr2[6]

//目标:arr2[0] ~ arr2[4]

for

(

int

i

=

0

;

i

<

sz

;

i

++

)

printf

(

"%d "

,

arr2

[

i

]

)

;

// 3 4 5 6 7 6 7 8 9 10

return

0

;

}

这是

从后往前

进行拷贝的,拷贝结果和预期效果一样(但不一定是对的,是依赖编译器的实现方式和效果),但是

arr2

arr2 + 2

属于同一个数组,源区域和目标区域发生

重叠

,使用

memcpy

会导致

未定义行为

,我们再来看

从前往后拷贝

的情况:

下面列出在下面的情况下不能使用

memcpy

函数:

不能使用 memcpy 的情况

原因

正确做法

源内存和目标内存发生

重叠

memcpy

不保证重叠拷贝的正确性,会导致未定义行为

使用

memmove

源指针或目标指针是

空指针

memcpy

会访问非法内存,程序可能崩溃

拷贝前判断指针是否为

NULL

拷贝长度

超过源内存大小

会读取越界内存,导致未定义行为

确保拷贝字节数不超过源空间大小

拷贝长度超过

目标内存大小

会写入越界内存,可能破坏其他数据

确保目标空间足够大

拷贝的字节数

写死为固定数字

不同平台上数据类型大小可能不同,容易出错

使用

sizeof

计算拷贝大小

目标内存是

只读区域

向只读内存写入会导致程序崩溃

确保目标区域可写

1.2 模拟实现

include

include

include

void

*

my_memcpy

(

void

*

dest

,

const

void

*

src

,

size_t

num

)

//用const来修饰src,代表源头数据中的值不能被修改

{

void

*

p

=

dest

;

//存储目标空间的起始地址

assert

(

dest

&&

src

)

;

//断言dest和src不为空

while

(

num

--

)

{

*

(

(

char

*

)

dest

)

=

*

(

(

char

*

)

src

)

;

dest

=

(

char

*

)

dest

+

1

;

src

=

(

char

*

)

src

+

1

;

}

return

p

;

}

int

main

(

)

{

int

arr1

[

10

]

=

{

0

}

;

int

arr2

[

]

=

{

1

,

2

,

3

,

4

,

5

,

6

,

7

,

8

,

9

,

10

}

;

int

sz

=

sizeof

(

arr1

)

/

sizeof

(

arr1

[

0

]

)

;

//使用sizeof(arr2[0])来表示要拷贝的字节数便于代码的可移植性

my_memcpy

(

arr1

,

arr2

,

3

*

sizeof

(

arr2

[

0

]

)

)

;

for

(

int

i

=

0

;

i

<

sz

;

i

++

)

printf

(

"%d "

,

arr1

[

i

]

)

;

return

0

;

}

画图演示:

  1. memmove

项目

内容

函数名

memmove

头文件

include

函数原型

void memmove(void destination, const void *source, size_t num);

功能

source

指向的内存位置开始,复制

num

个字节的数据到

destination

指向的内存位置

参数

destination

目标空间地址,拷贝后的数据存放到这里

参数

source

源空间地址,要拷贝的数据从这里开始

参数

num

要拷贝的数据所占的字节数

返回值

返回目标空间的起始地址,即

destination

重要特点

memmove

可以处理源内存块和目标内存块重叠的情况

memcpy

的区别

memcpy

不适合处理重叠内存,而

memmove

可以正确处理重叠内存

2.1 代码演示

include

include

int

main

(

)

{

int

arr1

[

10

]

=

{

0

}

;

int

arr2

[

]

=

{

1

,

2

,

3

,

4

,

5

,

6

,

7

,

8

,

9

,

10

}

;

int

sz

=

sizeof

(

arr2

)

/

sizeof

(

arr2

[

0

]

)

;

memmove

(

arr1

,

arr2

,

4

*

sizeof

(

arr2

[

0

]

)

)

;

for

(

int

i

=

0

;

i

<

sz

;

i

++

)

printf

(

"%d "

,

arr1

[

i

]

)

;

//1 2 3 4 0 0 0 0 0 0

return

0

;

}

2.2 模拟实现

include

include

include

void

*

my_memmove

(

void

*

dest

,

const

void

*

src

,

size_t

num

)

{

void

*

p

=

dest

;

// 保存目标空间的起始地址,最后用于返回

assert

(

dest

&&

src

)

;

if

(

dest

<

src

)

// 如果目标地址在源地址之前,从前往后拷贝

{

//前->后

while

(

num

--

)

{

*

(

char

*

)

dest

=

*

(

char

*

)

src

;

dest

=

(

char

*

)

dest

+

1

;

src

=

(

char

*

)

src

+

1

;

}

}

else

{

//后->前

while

(

num

--

)

// 如果目标地址在源地址之后,从后往前拷贝

{

*

(

(

char

*

)

dest

+

num

)

=

*

(

(

char

*

)

src

+

num

)

;

}

}

return

p

;

}

int

main

(

)

{

int

arr1

[

10

]

=

{

0

}

;

int

arr2

[

]

=

{

1

,

2

,

3

,

4

,

5

,

6

,

7

,

8

,

9

,

10

}

;

int

sz

=

sizeof

(

arr1

)

/

sizeof

(

arr1

[

0

]

)

;

my_memmove

(

arr2

+

3

,

arr2

,

4

*

sizeof

(

arr2

[

0

]

)

)

;

for

(

int

i

=

0

;

i

<

sz

;

i

++

)

printf

(

"%d "

,

arr2

[

i

]

)

;

//1 2 3 1 2 3 4 8 9 0

return

0

;

}

画图演示:

从后向前的例子:(上述代码的模拟实现)

从前向后的例子:

  1. memset

项目

内容

函数名

memset

头文件

include

函数原型

void memset(void ptr, int value, size_t num);

功能

ptr

指向的内存位置开始,将连续

num

个字节的空间设置为指定的值

参数

ptr

指针,指向要设置的内存空间,也就是目标内存空间的起始地址

参数

value

要设置的值,函数会将

value

转换为

unsigned char

类型后进行设置

参数

num

要设置的内存长度,单位是字节

返回值

返回目标内存空间的起始地址,即

ptr

重要特点

memset

是按

字节设置内存内容的

,不是按

数据类型逐个赋值

注意事项

可以安全地把内存设置为

0

,但不能随意用它把

int

数组设置为

1

2

等非零整数

3.1 代码演示

include

include

int

main

(

)

{

char

str

[

]

=

"abcdef"

;

memset

(

str

,

'x'

,

6

)

;

printf

(

"%s\n"

,

str

)

;

//xxxxxx

return

0

;

}

3.2 总结

当有⼀块内存空间需要设置内容的时候,就可以使⽤

memset

函数,值得注意的是

memset

函数对内存单元的设置是

以字节为单位

的。

注意,不能随意用它把

int

数组设置为非零整数,结果会有问题

  1. memcmp

项目

内容

函数名

memcmp

头文件

include

函数原型

int memcmp(const void ptr1, const void ptr2, size_t num);

功能

ptr1

ptr2

指向的内存位置开始,比较连续

num

个字节的内容

参数

ptr1

指针,指向第一块要比较的内存空间

参数

ptr2

指针,指向第二块要比较的内存空间

参数

num

要比较的字节数

返回值

< 0

第一处不同字节中,

ptr1

指向的

字节值

小于

ptr2

指向的

字节值

返回值

= 0

两块内存在前

num

个字节内完全相同

返回值

0

第一处不同字节中,

ptr1

指向的字节值大于

ptr2

指向的字节值

重要特点

memcmp

是按

字节比较内存内容

不是按数据类型整体比较

4.1 代码演示

int

main

(

)

{

int

arr1

[

]

=

{

1

,

2

,

3

,

4

,

5

}

;

// 04 00 00 00

int

arr2

[

]

=

{

1

,

2

,

3

,

1

,

5

}

;

// 01 00 00 00

int

r

=

memcmp

(

arr1

,

arr2

,

5

*

sizeof

(

arr1

[

0

]

)

)

;

printf

(

"%d\n"

,

r

)

;

//1

return

0

;

}

画图演示:

4.2 总结

memcmp

是一个按字节比较两块内存内容的函数,可以指定比较长度,并通过返回值表示大小关系。

memcmp

函数在比较int数组的时候,

memcmp

是按字节进行比较,不是按int数值进行比较

查看原文


🏷 标签: C语言, 内存操作, 标准库函数