Al usar calloc en función interna, cambia el puntero pasado como argumento de función

No entiendo por qué el segundo bucle printf genera datos diferentes al primer bucle printf que se realizó dentro del scope de la función. ¿Puede ser que el puntero se cambie de alguna manera dentro de la función, de modo que cuando retorne devuelva un valor diferente?

Salida:

Primera función dentro de printf:
Piezas TMP | 01245
Piezas X | 40001
Partes Y | 98760

Segunda función externa de printf, en main:
Devuelve jiberish y no es lo mismo que cuando se imprime dentro de la función. Intenté fprintf para poder pegar rápidamente los resultados aquí, pero luego recibí un error de stack de llamadas no informativo.

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

¿Alguien puede por favor arrojar algo de luz sobre mi problema? ¿Porque no estoy seguro de lo que estoy haciendo mal?

La asignación de parts dentro de la función no tiene efecto en las char **parts de main . Para modificarlo, debe pasar un puntero a parts y agregar un nivel adicional de direccionamiento indirecto (sí, ahora obtendrá tres asteriscos).

El código que divide los datos en cadenas también es incorrecto: debe asignar una matriz de punteros de caracteres y luego copiar cada token en esa matriz individualmente.

 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]); } } 

Hice tres cambios a tu código:

  • Se reemplazó el calloc con malloc : de todos modos, se inicializan todos los elementos, por lo que no hay razón para rellenar el bloque a cero
  • Se retiraron los moldes delante de malloc , esto no es necesario en C
  • Se agregó uno a strlen(tempPart) : lo necesita para cadenas terminadas en nulo.

Hay diferentes errores:

Cuando se pasa un parámetro a una función, siempre se copia. Usted le dio un char **parts y se copia.

Dentro de la función sobrescribe la entrada copiada con la nueva dirección del puntero de calloc .

Considere un ejemplo más fácil:

 void doSomething(int a){ a=5; } ///... int b = 6; doSomething(b); 

Cuando llama a doSomething(b) , su b no cambia. Si desea cambiarlo, debe pasar un puntero a b .

 void doSomething(int* a){ *a=5; } ///... int b = 6; doSomething(&b); 

Lo mismo char* con su matriz char* .

Tiene char** parts en su main, que desea configurar en la matriz asignada. Así que tienes que pasar su puntero. y escriba la dirección obtenida en el puntero desreferenciado.

El otro gran error es que le das la palabra equivocada al primer calloc . Debe ser sizeof(char*) .

Tu rutina debe comenzar así:

 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; //... 

(todos los accesos a partes en la función tienen que desreferir partes)

y la llamada tiene que verse como:

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