理解strtok返回的指针

时间:2015-04-30 00:15:54

标签: c pointers strtok

我有这个代码,我在其中标记字符串并搜索值。

char string[]="Name=Marcus&greeting=goodmorning";
char* Name=parsePostData("Name",string);




char* parsePostData(char s[],char t[])
{
  char *pch;
  char *pp="Marcus";

  char tCpy[512];//Make a copy. Otherwise, strtok works on the char pointer, and original char array gets modified/ corrupted.
  strcpy(tCpy,t);
  pch = strtok (tCpy,"=&");
  while (pch != NULL)
  {
      if(strcmp(pch,s)==0) {
            pch= strtok (NULL, "&"); 
            //Case 1. what I need. but it is causing issues 
            //after I write to flash, and restart the board.
            return pch;   

            //Case 2. Forced test case. works perfect.             
            //return pp;


      }else{
        pch = strtok (NULL, "=&");  
      }
  }

}

函数内部的两个案例有什么区别?

1 个答案:

答案 0 :(得分:1)

  

函数内部的两个案例有什么区别?

案例1。

正如有几个人现在告诉你的那样,序列

pch = strtok (tCpy,"=&");
/* ... */
pch= strtok (NULL, "&");

导致pch成为本地数组tCpy的指针(如果原始字符串不包含' ='或'&& #39)。因为tCpy本地数组,所以它在函数末尾超出范围,此时任何指向它的指针都不再有效。实际上,它占用的内存可能会被下一个名为。

的函数重用

案例2。

代码

char *pp="Marcus";

初始化pp以指向一个静态的匿名字符数组,其内容是以空字符结尾的字符串"Marcus"。由于数组具有静态存储持续时间,因此在函数退出后,指向它的指针仍然有效。

解决此问题有三个主要选项:

  1. 调用者为字符串副本提供预分配存储的功能。这可能是一个工作数组(不一定是动态分配的),或者它可以采取只是让函数使用字符串的形式,调用者负责在必要时制作副本。
  2. 该函数动态为复制分配存储空间。有很多方法可以实现,但strdup()功能是一种快速简便的分配和复制方式。
  3. 您可以将数组tCpy设为静态。然后指向它的指针在从函数返回后仍然有效,但是每次调用该函数时都会重用该空间,可能会改变指针所指向的文本。
  4. 注意WELL:函数分配内存以返回调用者的任何变体都会让调用者负责释放该内存不再使用时。这样做需要一个指向已分配块的 start 的指针,而不是指向中间的某个随机位置,因此您需要传回两个指针以使其工作(一个通过参数)。 / p>

    完成所有操作后,我认为选择1的变体是明智的。如果是我,我会让函数使用传递给它的字符串。

    <强>更新 此外,在案例2中,程序图像包含指针指向的数据。假设它始终在同一地址加载,保存和恢复指针值而不是它指向的值实际上只适用于该程序,因为您通过在其上加载程序图像来重新初始化指向内存的内存。如果将字符串复制到工作数组中,则同样不适用,因为即使数组具有静态持续时间,也不会使用要恢复的数据进行初始化。