代码之家  ›  专栏  ›  技术社区  ›  Rory Thoman

用于返回C中值的可用内存

  •  1
  • Rory Thoman  · 技术社区  · 10 年前

    我有一个函数调用另一个函数,该函数创建一个唯一的ID,并通过malloc()将其作为字符串返回。

    我的问题是,如何在函数外释放内存?或者什么是做我想做的事情的更好方法。

    我的请求ID的函数:

    void addCustomer(TennisStoreType* ts){
    
       CustomerNodePtr newcustdata;
       int datapos = 0;
    
       newcustdata = malloc(sizeof(CustomerNodeType));
    
       while (datapos <= CUSTDATA_POSITIONS) {
    
          char userinput[BUFFER_SIZE];
    
          switch (datapos) {
             case 0:
                strcpy(newcustdata->custID, createCustID(ts));
                break;
       }
    }
    

    返回uniqueID的函数:

    char* createCustID(TennisStoreType* ts) {
    
       char *custID;
    
       custID = (char *)malloc(CUSTID_LEN + 1 * sizeof(char));
    
       if (ts->customerCount + 1 >= FOURDIGITS) {
          sprintf(custID, "C%i\n", ts->customerCount + 1);
    
       } else if (ts->customerCount + 1 >= THREEDIGITS){
          sprintf(custID, "C0%i\n", ts->customerCount + 1);
    
       } else if (ts->customerCount + 1 >= TWODIGITS) {
          sprintf(custID, "C00%i\n", ts->customerCount + 1);
    
       } else {
          sprintf(custID, "C000%i\n", ts->customerCount + 1);
       }
    
       return custID;
    }
    

    那么我该如何释放已复制到newcustdata->客户ID?我需要吗?还是有更好的方法来做这件事?

    提前感谢。

    2 回复  |  直到 10 年前
        1
  •  1
  •   user3386109    10 年前

    您可以完全消除该功能。线路

    strcpy(newcustdata->custID, createCustID(ts));
    

    可以简单地写为

    sprintf( newcustdata->custID, "C%04d", ts->customerCount + 1 );
    

    当然,前提是 custID 是至少6个字符的数组,例如。

    char custID[8];
    

    笔记:

    1. 我通常是圆的 char 阵列大小最多为8的倍数,因为结构 填充无论如何都会浪费字节。
    2. 我删除了 \n 因为有换行符似乎不正确 字符,但当然可以将其添加回。

    如果您真的喜欢该功能,并希望保留它,请替换

    switch (datapos) {
       case 0:
          strcpy(newcustdata->custID, createCustID(ts));
          break;
    }
    

    用这个

    char *temp;
    switch (datapos) {
       case 0:
          temp = createCustID(ts);
          strcpy(newcustdata->custID, temp);
          free( temp );
          break;
    }
    

    这将在复制后释放内存。

        2
  •  1
  •   cncsnw    10 年前

    createCustID()函数将分配一些内存,然后通过返回从malloc()获得的指针将其返回给调用者。

    调用例程在完成结构时,可以(而且必须)通过将相同的指针传递给free()来释放内存。

    在您的示例中,您需要扩展addCustomer()中的逻辑,以将它从createCustID()接收到的指针保留足够长的时间,以便(1)测试它是否为空,(2)根据需要在本地复制内容,以及(3)释放接收到的块。

    正如其他人所指出的那样,您可能会发现将接收到的块构建到正在组装的数据结构中,而不是复制它更有效。但是,您仍需要释放块,作为处理更大数据结构的逻辑的一部分。

    您需要使用这种类型的代码仔细规划代码路径,以便始终知道谁“拥有”分配的块,并负责在不再需要时释放它。

    此外,您必须 总是 对照null检查malloc()的返回值。如果malloc未能提供所需的内存,则需要适当地处理错误;而不仅仅是将数据写入空指针。