是否在函数内部使用calloc更改作为函数参数传递的指针

是否在函数内部使用calloc更改作为函数参数传递的指针,c,C,我不明白为什么第二个printf循环输出的数据与在函数范围内完成的第一个printf循环不同。指针是否会在函数内部以某种方式更改,以便在返回时返回不同的值 输出: 函数内部的第一个printf: 零件TMP | 01245 第X部分| 40001 第Y部分| 98760 第二个printf外部函数,主函数: 它返回jiberish,与在函数内部打印时不同。 我尝试使用fprintf,以便快速将结果粘贴到此处,但随后收到一个非信息性调用堆栈错误 #include <stdio.h> #

我不明白为什么第二个printf循环输出的数据与在函数范围内完成的第一个printf循环不同。指针是否会在函数内部以某种方式更改,以便在返回时返回不同的值

输出:

函数内部的第一个printf:
零件TMP | 01245
第X部分| 40001
第Y部分| 98760

第二个printf外部函数,主函数:
它返回jiberish,与在函数内部打印时不同。 我尝试使用fprintf,以便快速将结果粘贴到此处,但随后收到一个非信息性调用堆栈错误

#include <stdio.h>
#include <stdlib.h>
#include "string.h"

void ProtocolParse_Start(int *numParts,char **parts, char *str, const char* partsDelim )
{
  int partCount = strChrCount(str,'~');
  *numParts = partCount;

  parts = (char**)calloc(partCount,sizeof(char));
  char *tempPart;


  tempPart = strtok (str,partsDelim);
  parts[0] = (char*)calloc(strlen(tempPart),sizeof(char));
  strcpy(parts[0],tempPart);


  int i =1;
  for(; i < partCount; i++)
  {
      tempPart = strtok (NULL, partsDelim);
      parts[i] = (char*)calloc(strlen(tempPart),sizeof(char));
      strcpy(parts[i],tempPart);
  }

   i =0;
  for(; i < partCount; i++)
  {
      printf ("%Parts %s\n",parts[i]);
  }

}

void ProtocolParse_End(int numParts,char **parts)
{
    int i = 0;
    for (; i < numParts; i++)
        free (parts[i]);

    free (parts);
}


int main()
{
    char proto[32] = "TMP|01245~X|40001~Y|98760~";

    char **parts;
    int numParts;
    ProtocolParse_Start(&numParts, parts,proto,"~");


     int i =0;
     for(; i < numParts; i++)
     {
          printf ("%Parts %s\n",parts[i]);
     }

    ProtocolParse_End(numParts,parts);

    return 0;
}
#包括
#包括
#包括“string.h”
void ProtocolParse_Start(int*numParts,char**parts,char*str,const char*partsDelim)
{
int partCount=strcrcount(str,“~”);
*numParts=零件计数;
parts=(char**)calloc(partCount,sizeof(char));
字符*临时部分;
tempPart=strtok(str,partsDelim);
parts[0]=(char*)calloc(strlen(tempPart),sizeof(char));
strcpy(零件[0],临时零件);
int i=1;
对于(;i

谁能解释一下我的问题吗。因为我不确定我做错了什么???

函数中
部分的赋值对
字符**parts
main
没有影响。为了修改它,您需要传递一个指向
部分的指针,并添加一个额外级别的间接寻址(是的,您现在会得到三个星号)

将数据划分为字符串的代码也不正确:您需要分配一个字符指针数组,然后将每个令牌分别复制到该数组中

void ProtocolParse_Start(int *numParts, char ***parts, char *str, const char* partsDelim )
{
  int partCount = strChrCount(str,'~');
  *numParts = partCount;

  *parts = malloc(partCount * sizeof(char*));

  char *tempPart;
  tempPart = strtok (str,partsDelim);
  (*parts)[0] = malloc(strlen(tempPart)+1);
  strcpy((*parts)[0], tempPart);

  int i =1;
  for(; i < partCount; i++)
  {
      tempPart = strtok (NULL, partsDelim);
      (*parts)[i] = malloc(strlen(tempPart)+1);
      strcpy((*parts)[i],tempPart);
  }

  i =0;
  for(; i < partCount; i++) {
      printf ("%Parts %s\n", (*parts)[i]);
  }

}
void ProtocolParse_Start(int*numParts,char***parts,char*str,const char*partsDelim)
{
int partCount=strcrcount(str,“~”);
*numParts=零件计数;
*parts=malloc(partCount*sizeof(char*);
字符*临时部分;
tempPart=strtok(str,partsDelim);
(*部分)[0]=malloc(strlen(tempPart)+1);
strcpy((*部分)[0],临时部分);
int i=1;
对于(;i
我对您的代码做了三个更改:

  • calloc
    替换为
    malloc
    :无论如何都要初始化每个元素,因此没有理由对块进行零填充
  • 删除了malloc前面的强制类型转换
-这在C中不是必需的
  • 在strlen(tempPart)
  • 中添加了一个-对于以null结尾的字符串,您需要这个
      有不同的错误:

      将参数传递给函数时,它总是被复制的。 你给了一个
      char**parts
      ,它被复制了

      在函数内部,您使用
      calloc
      ed指针的新地址覆盖复制的输入

      考虑一个更简单的例子:

      void doSomething(int a){
        a=5;
      }
      ///...
      int b = 6;
      doSomething(b);
      
      当您调用
      doSomething(b)
      时,您的b不会更改。 如果要更改,必须将指针传递到
      b

      void doSomething(int* a){
        *a=5;
      }
      ///...
      int b = 6;
      doSomething(&b);
      
      您的
      char*
      数组也是如此

      您的main中有
      char**parts
      ,希望将其设置为分配的数组。 所以你必须传递它的指针。并将获得的地址写入解引用指针

      另一个大错误是,您将错误的soze指向第一个
      calloc
      。它应该是
      sizeof(char*)

      你的日常工作应该这样开始:

      void ProtocolParse_Start(int *numParts,char ***parts, char *str, const char* partsDelim )
      {
        int partCount = strChrCount(str,'~');
        *numParts = partCount;
      
        *parts = (char**)calloc(partCount,sizeof(char*));
        char *tempPart;
        //...
      
      (对函数中部件的所有进一步访问必须取消对部件的引用)

      电话必须是这样的:

      ProtocolParse_Start(&numParts, &parts,proto,"~");
      

      删除C++标签,以避免所有人告诉你使用<代码> STD::String 。因为这是C代码。抱歉,这只是快速点击了自动建议的标签。谢谢,我还是蚱蜢:)使用MALOC代替CaloC我理解。我只是用这种方式写的,这样当我把代码移到一个McC++项目时,我不需要以后再修改它。我读到strtok返回令牌并自动null终止它,但在查找大小时忘记添加+1。感谢您的帮助。我尝试了您的代码,但在尝试执行第三个malloc时:(*parts)[I]=malloc(strlen(tempPart)+1);在我是1的地方,它失败了。有什么想法吗?@DR.您正在传递
      协议中的地址解析\u Start(&numParts,&parts,proto,“~”呼叫,对吗?@DR.代码在ideone上运行良好。您需要修复
      %
      部分前面的
      %
      ,因为
      printf
      将其视为无效的格式字符。愚蠢的我是在做(*Parts[0]),而不是(*Parts)[0]不只是想复制,所以重新键入了它。对不起,谢谢。我的印象是,当传递字符指针时,它是通过引用传递的。但它似乎是通过读取您的答案的值传递的?我不明白为什么我应该使用sizeof(char*)而不是像我那样使用sizeof(char)。因为sizeof(char*)不一定等于8位或1字节,这取决于它是在32位还是64位计算机上运行。所以我认为使用sizeof(char)是正确的,因为它肯定意味着1字节?