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

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

输出:

第一个printf内部function:
零件TMP | 01245
零件X | 40001
零件Y | 98760

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

#include  #include  #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; } 

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

函数内部的赋值对mainchar **parts没有影响。 为了修改它,你需要传递一个指向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]); } } 

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

  • malloc替换calloc :无论如何都要初始化每个元素,因此没有理由对块进行零填充
  • 删除了malloc前面的强制转换 - 这在C中是不必要的
  • strlen(tempPart)添加了一个 - 你需要这个用于空终止的字符串。

有不同的错误:

将参数传递给函数时,始终会复制该参数。 你给了一个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,"~");