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

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。

正如几个人现在告诉你的,顺序

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


导致pch是指向本地数组tCpy的指针(如果原始字符串不包含'='或'&',则为NULL)。由于tCpy是局部数组,因此在函数末尾超出范围,此时指向该数组的所有指针均不再有效。实际上,它所占用的内存可能会被下一个调用的函数重用。



情况2

代码

char *pp="Marcus";


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



您可以通过以下三种主要方法解决此问题:


调用方为字符串副本提供功能预分配的存储。那可以是一个工作数组(不一定是动态分配的),也可以采取只让函数使用字符串的形式,并在必要时由调用方负责进行复制。
该功能动态分配副本的存储空间。有很多方法可以使用,但是strdup()函数是一种快速,轻松地一步分配和复制的方法。
您可以将数组tCpy设为静态。然后,从函数返回后,指向该指针的指针将保持有效,但是在对该函数的每次调用中都将重新使用该空间,可能会更改指针指向的文本。


注意:在分配内存以返回给调用方的函数上的任何变化都使调用方有责任在不再使用该内存时释放该内存。这样做需要一个指向已分配块的开始的指针,而不是指向中间某个随机位置的指针,因此您需要传回两个指针以使该指针起作用(一个通过参数)。

说完所有内容后,我认为您应该在选项1上选择一个变体。就我个人而言,我只是让函数使用传递给它的字符串。

更新:
此外,在情况2中,程序映像包含指针指向的数据。假设它始终加载在同一地址,则保存和恢复指针值而不是指针指向的值可能仅对该程序有效,因为您通过在其上加载程序映像来重新初始化指向的内存。如果将字符串复制到工作的数组中,则不会应用相同的内容,因为即使该数组具有静态持续时间,也不会使用要恢复的数据进行初始化。

07-28 02:53
查看更多