有关memcpy函数如何运行的说明?
#include <stdio.h>
#include <string.h>
char lists[10][25];
char name[10];
void main()
{
scanf("%s" , lists[0]);
memcpy(name , lists[0], 25);
printf("%s\n" , name);
}
在上面的代码我预定义的字符数组“名”的大小为10。 现在,当我给输入为:有关memcpy函数如何运行的说明?
输入 - abcdefghijklmnopqrstuvwxy
我得到的输出是相同的字符串:abcdefghijklmnopqrstuvwxy
应该不会输出为:abcdefghij?
即使阵列的大小限制为10,这将如何变得可能?
因为它不知道它正在写入的已分配内存的大小,所以你就不知道写入额外数据的位置了。您可能不在其他平台上,或使用不同的编译器或不同的优化设置。
当将size
参数传递给memcpy()
时,最好考虑目标存储器的大小。
使用字符数组时,如果想要更安全地关于不超限内存,可以使用strncpy()
。它会照顾在正确的地方插入尾随NULL
。
首先,数组是指针。在C中,没有像Java那样的长度检查。
当您编写char a[2];
时,操作系统会为您提供2个字符的内存空间。 例如,让存储器是
|1|2|3|4|5|6|7|8|9|10|11|12|
a
a
是指向的地址1。a[0] = 0;
与*(a+0) = 0
相等,这意味着write 0 to the address a + offset 0
。
因此,如果您尝试写入未分配的地址,可能会发生意想不到的情况。
例如,让我们说我们有char a[2];char b[2];
和存储器映射
|1|2|3|4|5|6|7|8|9|10|11|12|
a b
然后a[2] = 0
等于b[0] = 0
。但是如果这个地址是另一个程序的地址,那么会出现分段错误。
尝试程序(它可能没有编译器的优化工作):
#include <stdio.h>
#include <string.h>
char a[4];
char b[4];
void main()
{
scanf("%s" , a); // input "12345678"
printf("%s\n" , b); // print "5678"
}
memcpy
刚刚从一个地址复制到其他的数据你说的大小。
在你的例子中,你是luky,因为你访问的所有地址分配给你的程序(在你的内存页面内)。
在C/C++中,您有责任正确处理内存。另外,请记住,字符串以char \0
结尾,因此在数组内我们通常有9个字符和\0
。
我认为你在这里有一个错字:“a [0] = 0;与*(a + 1)= 0相等,意思是写0到地址a +偏移量0。 – MFisherKDX
当然可以。谢谢。 (现在正确) – GramThanos
“| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ab然后a [2] = 0等于b [0] = 0 “。如果你依靠这种行为,你就会受到伤害。不知道编译器/优化器可能做什么。 – MFisherKDX
这是一个* undefined behavior *的例子,这意味着可能发生任何事情。包括程序正常工作。 – klutt
你的代码在线以外着色,非常基本的UB。如果你想让它炸毁并重新格式化磁盘,那么你需要更多的颜色。交换这两个变量声明是值得一试的。 –
大多数语言都会阻止程序员写入数组的末尾。 C没有。这是你的责任。 – jarmod