【问题标题】:String stored in struct prints incorrectly存储在结构中的字符串打印不正确
【发布时间】:2013-11-04 00:05:09
【问题描述】:

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

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);

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

【问题讨论】:

    标签: c string struct char


    【解决方案1】:

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

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

    如果您删除此行,您的程序 sn-p 应该可以工作:

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

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

    还有一些想法……

    1) 考虑使用union 而不是int 来代替value

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

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

    【讨论】:

    • 出色的工作!我会使用 union,但这是针对学校的,我需要使用 int。无用的varPtr->dType;声明是一个错误,我最初将它分配给它,但删除了那部分代码以进行调试。感谢您指出这一点!而且我完全不用动态分配内存,我从来没有在我的最终代码中使用过 calloc 或 malloc。
    【解决方案2】:

    这个:

    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;
    }
    

    【讨论】:

    • 你给了我多种选择,所以+1。我正在考虑让 initVar 返回一个指向 VarType 的指针,特别是因为这会让它“感觉”更像是面向对象的语法,但我最终决定远离它。我也从未意识到 VarType vars[3] 已经分配了内存,这应该很明显。感谢您的洞察力!
    【解决方案3】:

    去掉这行就ok了

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

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

    【讨论】:

      【解决方案4】:

      这个:

      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() 的那一行。

      【讨论】:

        猜你喜欢
        • 2011-07-13
        • 2015-04-25
        • 2021-03-30
        • 1970-01-01
        • 1970-01-01
        • 2012-09-13
        • 2021-06-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多