1

我的程序中定义了几种数据类型,其中一种如下所示:

typedef struct {
  char     name[MAX_STR];
  int      value;
  DataType dType; 
} VarType;

我想使用我定义如下的函数“初始化”它:

void initVar(VarType *varPtr, char *name, int *val, DataType d)
{
  varPtr = (VarType *) calloc(1,sizeof(VarType));
  strcpy(varPtr->name, name);
  varPtr->dType;

  /* we have to store it differently depending on the type, be careful! */
  if(d==C_INT_PTR)
    varPtr->value = (int)(val);
  else if(d==C_INT)
    varPtr->value = *val;

  /* NOTE THE FOLLOWING LINE */
  printf("The variable name prints properly here: %s\n", varPtr->name);
}

最后,我想在代码的其他地方使用这些结构和方法,但是当我在使用字符串文字设置名称后检查名称时,它会打印出乱码,即使在initVar()函数中打印得非常好。

/* let's store the variables we're gonna put in the frame */
VarType vars[3];

initVar(&vars[0], "num", &num, C_INT);
/* NOTE THE FOLLOWING LINE */
printf("This one prints like jibberish: %s\n",vars[0].name);

为什么它不再打印正确的字符串了?

4

4 回答 4

3

在您的initVar函数中,您立即覆盖varPtr变量,使其指向新分配的内存而不是&vars[0]. 函数中的所有内容都使用这个新分配的内存,包括最后一个 printf,因此它可以正常工作。

不幸的是,这意味着您实际上根本没有修改vars[0]。当您从函数返回时,您会泄漏分配的内存,并且vars[0]保持未初始化状态,因此会出现乱码。

如果您删除此行,您的程序片段应该可以工作:

varPtr = (VarType *) calloc(1,sizeof(VarType));

但是,目前尚不清楚这是否是您总体上想要做的事情。

还有一些想法...

1)考虑使用 aunion而不是intfor value

2)该语句varPtr->dType;不做任何事情,可以删除。

3)如果您尝试使用calloc将结构归零,请尝试使用memset

于 2013-10-25T02:49:17.417 回答
1

这个:

VarType vars[3];

VarType已经初始化了一个大小为 3的数组类型。

这里:

varPtr = (VarType *) calloc(1,sizeof(VarType));

您正在覆盖vars[0]

1) 删除varPtr = (VarType *) calloc(1,sizeof(VarType))

或者

2)不要VarType在函数外部声明,而是将函数类型更改为VarType,以便它返回一个VarType指针

如:

VarType* initVar(char *name, int *val, DataType d)
{
  VarType* varPtr = (VarType *) calloc(1,sizeof(VarType));
  strcpy(varPtr->name, name);
  varPtr->dType;

  /* we have to store it differently depending on the type, be careful! */
  if(d==C_INT_PTR)
    varPtr->value = (int)(val);
  else if(d==C_INT)
    varPtr->value = *val;

  /* NOTE THE FOLLOWING LINE */
  printf("The variable name prints properly here: %s\n", varPtr->name);
  return varPtr;
}
于 2013-10-25T03:25:26.823 回答
0

这个:

varPtr = (VarType *) calloc(1,sizeof(VarType));

创建一个本地指针varPtr,当你的函数退出时它会被销毁。这就是为什么它在您的函数中打印 OK,但在调用者中却没有。您需要将指针传递给它,例如:

void initVar(VarType ** varPtr, char *name, int *val, DataType d)
{
    VarType * temp_varPtr = calloc(1,sizeof(VarType));

    /*  Rest of function  */

    *varPtr = temp_varPtr;
}

但是,您的函数还有很多其他错误,其中最重要的是您在VarType调用它之前设置了一个数组,然后尝试calloc()在设置数组时已经分配的内存。您应该摆脱其中的那条线calloc()

于 2013-10-25T02:47:42.343 回答
0

去掉这行就OK了

 varPtr = (VarType *) calloc(1,sizeof(VarType))

这会创建一个局部变量,在退出函数时会自动销毁

于 2013-10-25T03:05:01.413 回答