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

时间:2014-10-10 18:42:55

标签: c

我不明白为什么第二个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;
}

任何人都可以对我的问题有所了解。因为我不确定我做错了什么?

2 个答案:

答案 0 :(得分:2)

在函数内部parts的分配对char **parts的{​​{1}}没有影响。为了修改它,你需要传递一个指向main的指针,并添加一个额外的间接级别(是的,你现在得到三个星号)。

将数据分区为字符串的代码也是错误的:您需要分配一个字符指针数组,然后将每个标记分别复制到该数组中。

parts

我对您的代码进行了三处更改:

  • 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]); } } 替换calloc:无论如何都要初始化每个元素,因此没有理由对块进行零填充
  • malloc前删除了演员表 - 这在C
  • 中不是必需的
  • malloc中添加了一个 - 你需要这个用于空终止字符串。

答案 1 :(得分:0)

有不同的错误:

将参数传递给函数时,始终会复制该参数。 您提供了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,您希望将其设置为已分配的数组。 所以你必须传递它的指针。并将获得的地址写入解除引用的指针。

另一个重大错误是,你对第一个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,"~");