为啥结构数组的 memset 会改变程序行为?
Posted
技术标签:
【中文标题】为啥结构数组的 memset 会改变程序行为?【英文标题】:Why memset of array of structure changing the program behaviour?为什么结构数组的 memset 会改变程序行为? 【发布时间】:2016-05-20 08:15:17 【问题描述】:#include <stdio.h>
#include <string.h>
#define PIPE "myPipeName"
typedef enum
ID1,
ID2
TEST_ID;
typedef struct
double dCnt;
TEST_ID id ;
Response;
int main()
char pipeName[256]=PIPE;
Response res[2];
printf("1. pipeName : %s , PIPE : %s\n",pipeName,PIPE);
memset(res,0,2*sizeof(res));
printf("2. pipeName : %s , PIPE : %s\n",pipeName,PIPE);
return 0;
实际输出:
管道名称:我的管道名称,管道:我的管道名称 管道名称:,管道:我的管道名称
预期 o/p:
管道名称:我的管道名称,管道:我的管道名称 管道名称:我的管道名称,管道:我的管道名称
请告诉我如何解决这个问题?
【问题讨论】:
2*sizeof(res)
...hmmm..
谢谢。今天我似乎失去了常识..但我不知道你们为什么投反对票。
【参考方案1】:
你已经超出了那里,它调用undefined behavior
改变
memset(res,0,2*sizeof(res));
^^^^^^^^^^^^
到
memset(res,0,sizeof(res));
或者,如果您更喜欢 multiplied 版本(也许是为了更好的可读性?),请使用
memset( res , 0 , 2 * sizeof(res[0]));
或
memset( res , 0 , 2 * sizeof(Response));
也就是说,未初始化的自动变量值是不确定的。 不要尝试使用它们。
【讨论】:
倍增版本不是一个好主意。如果res
的维度发生变化,我们必须维护它。
@songyuanyao 这就是为什么这是一个第二的选择,但无论如何,这是可能的。【参考方案2】:
Response res[2];//is an array of 2 Responses
sizeof(res);//get the size of the array in bytes
memset(res,0,2*sizeof(res));//the multiplication by the size of the array is not needed here and
//the memset is writing 0 out of bound of the array and probably
//into pipeName which would be treated as null terminator character
写出数组绑定是未定义的行为,所以改为:
memset(res,0,sizeof(res));
【讨论】:
【参考方案3】:您设置了错误的尺寸值
memset(res,0,2*sizeof(res));
应该是
memset(res,0,sizeof(res));
由于sizeof(res)
返回数组的大小(以字节为单位)。
或者
memset(res,0,2*sizeof(Response));
由于sizeof(Response)
返回响应类型定义结构的大小(以字节为单位)。
【讨论】:
以上是关于为啥结构数组的 memset 会改变程序行为?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 String 是 Value 类型,尽管它是类而不是结构?