C语言strcpy()特性及全局结构体数组字符串操作问题咨询
问题1解答
所有定义在全局存储区的对象都会被默认零初始化,你声明的GlobalDataPackage是全局数组,所以它包含的所有key数组、trail二维数组的每一个字节都会被初始化为\0,也就是你说的100个'\0'。
问题2解答
strcpy的运行逻辑是仅复制源字符串的内容(包括末尾的'\0'),不会清空目标空间的剩余内容:它会从源字符串的首地址开始逐字节拷贝,直到读取到源的'\0'终止符就停止,这个终止符也会被写入目标地址,目标地址中超出拷贝长度的原有内容会完全保留,不会被修改。
问题3解答
只要源字符串的长度(不含末尾'\0')不超过99,你给出的3种strcpy写法都是完全合法的:strcpy会正确把源字符串的所有字符写入目标key数组,并且自动在末尾追加'\0'终止符。
后续调用strlen、printf("%s")等依赖C字符串终止符的函数不会出现异常,因为这类函数只会读取到第一个'\0'就停止,key数组中后面未被覆盖的残留内容不会影响函数的执行结果。
问题4解答
当源是空字符串(即首字节就是'\0')时,strcpy只会向目标地址的首字节写入'\0',其余目标空间内容保持不变。此时目标字符串是合法的空字符串,strlen返回值为0,printf也不会输出任何内容,完全符合预期。
关于是否需要提前memset的补充
不需要每次调用strcpy前都用memset清空整个数组,属于多余操作:只要你能保证每次拷贝的源字符串都是合法的C字符串、且长度不超过99,strcpy写入的'\0'已经能保证目标字符串是合法的,完全不会有安全问题,memset只会带来不必要的性能开销。
只有当你有擦除敏感数据避免残留的需求时,才需要额外做memset操作。如果担心后续源字符串长度不可控会溢出,更推荐使用snprintf(key, sizeof(key), "%s", 源字符串)的写法,从根源上避免缓冲区溢出风险。
内容的提问来源于stack exchange,提问作者user16921148

