我正在尝试用偏移量为 2 的第二个字符串覆盖第一个字符串的一部分。
这是我的第二次尝试:
#include <stdio.h>
#include <string.h>
int main() {
char s[] = "Hello, World!";
char a[] = "aaa";
printf("%d\n", &s);
printf("%d\n", &s[2]);
memcpy(&s[2], a, sizeof(a)-1);
printf("%s\n", s);
return 0;
}
$ gcc -o test test2.c && ./test
520783106
520783108
Heaaa, World!
这是我的第一次尝试,它不起作用,在编译和段错误时发出警告:
#include <stdio.h>
#include <string.h>
int main() {
char s[] = "Hello, World!";
char a[] = "aaa";
printf("%d\n", &s);
printf("%d\n", sizeof(char)*2);
printf("%d\n", &s + (sizeof(char)*2));
memcpy(&s + (sizeof(char)*2), a, sizeof(a)-1);
printf("%s\n", s);
return 0;
}
$ gcc -o test test1.c && ./test
test1.c: In function ‘main’:
test1.c:12:4: warning: ‘memcpy’ writing 3 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
12 | memcpy(&s + (sizeof(char)*2), a, sizeof(a)-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test1.c:5:9: note: at offset 28 into destination object ‘s’ of size 14
5 | char s[] = "Hello, World!";
| ^
1547566642
2
1547566670
Hello, World!
Segmentation fault
有人可以向我解释为什么 test1 不起作用吗?
为什么 1547566642 和 2 之和等于 1547566670 而不是 1547566644 ?
我认为这是一个类型问题。 sizeof 返回的是 size_t 但 &s 的类型是什么?
提前感谢您的帮助。 ;)
s
是char[14]
。当获取其地址并添加 sizeof(char) * 2
时,您会在内存中步进 2 char[14]
。即向前 28 个字节。
您应该让
s
衰减为指向第一个元素的指针(char*
),然后 然后 添加 2:
memcpy(s + 2, a, sizeof(a) - 1);
// ^
// not &s
问题是
s
的类型是char[14]
,而不是char
。所以 &s
是指向 char[14]
的指针,而不是指向 char
的指针。当您对指针执行算术时,它会乘以它所指向的类型的大小。所以 &s + 2
与 &s[2]
不一样。 char[14]
的大小为 14
,因此这会为指针添加 28 个字节。
将
&s +
更改为 s +
。当您以这种方式使用数组名称时,它会自动衰减为指向第一个元素的指针。
一般来说,
&array[index]
相当于array+index
。