c - 重叠内存最佳实践

标签 c memmove

我对操作字符串时要内存的第三个参数有疑问。 strlen(string)strlen(string) + 1 似乎产生相同的结果。我认为 +1 部分会 包括终止 \0 但一切似乎都可以正常工作 两个都。这里有最佳实践要考虑吗?我已经看到了这两种情况的示例,但我不确定该采用哪种方式??

考虑以下 c 程序:

#include    <stdio.h>
#include    <string.h>
#include    <stdlib.h>
#include    <errno.h>

int main()
{
   char string1[20]="Hello World";
   char string2[20]="Hello World";
   printf("\nstring1=\"%s\"\n",string1);

   memmove(string1,string1+6,strlen(string1) + 1);

   printf("\nstring1 after memmove \"%s\" using strlen(string1) + 1\n",string1);

   printf("\nstring2=\"%s\"\n",string2);

   memmove(string2,string2+6,strlen(string2));

   printf("\nstring2 after memmove \"%s\" using strlen(sting2)\n",string2);

   return 0;
}

输出:

string1="Hello World"

string1 after memmove "World" using strlen(string1) + 1

string2="Hello World"

string2 after memmove "World" using strlen(sting2)

最佳答案

由于您从索引 6 开始,strlen(...)strlen(...) + 1 都过大了并在字符串末尾复制额外的 NUL 字节。它恰好有效,因为您制作了超大的 char[20] 数组,因此确实存在额外的 NUL。额外的数组槽用零填充,就像你写的一样:

char string1[20] = "Hello World\0\0\0\0\0\0\0\0\0";

你应该从两者中减去 6。如果你这样做,你会看到 strlen(... + 6) + 1strlen(...) + 1 - 6 是你想要的。从其中任何一个中删除 + 1 ,它不会复制 NUL 终止符,从而导致不同的结果:

string1 == "World\0World\0\0\0\0\0\0\0\0\0"  // with + 1, NUL copied
string2 == "World World\0\0\0\0\0\0\0\0\0"   // without + 1, NUL missing

关于c - 重叠内存最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56811034/

相关文章:

c++ - OpenGL ES 2 glGetActiveAtrib 和非 float

在 C 中连接具有特殊结尾字符的字符串

c - 数组长度计数异常

c - 为什么打印出来的变量地址是0x7fff935ad2b0这样的形式?

c - 将 char 分配给 char 指针时出现段错误(核心转储)

memcpy 或 memmove 可以返回与 dest 不同的指针吗?

c - 是否有 "lseek"要内存?

vector - Rust 中向量的元素如何左移?

c - 当我知道方向时,是否有 memmove 的优化版本?

c - 在 C 中使用 memmove 从字符串中删除子字符串