Pasando matriz de cadenas de caracteres para funcionar

Estoy tratando de pasar una serie de cadenas de caracteres (cadenas de estilo C) a una función. Sin embargo, no quiero colocar un tamaño máximo en la longitud de cada cadena que ingresa a la función, ni tampoco quiero asignar los arreglos dinámicamente. Aquí está el código que escribí primero:

#include  #include  #include  void fun(char *s[]) { printf("Entering Fun\n"); printf("s[1]=%s\n",(char *)s[1]); } int main(void) { char myStrings[2][12]; strcpy(myStrings[0],"7/2/2010"); strcpy(myStrings[1],"hello"); fun(myStrings); return(0); } 

Tengo una falla de seg cuando se ejecuta y la siguiente advertencia del comstackdor: stackov.c: En la función ‘main’: stackov.c: 17: warning: pasando el argumento 1 de ‘fun’ desde un tipo de puntero incompatible stackov.c: 5: nota: se esperaba ‘char **’ pero el argumento es de tipo ‘char (*) [12]’

Sin embargo, cuando cambio el main () a lo siguiente funciona:

 int main(void) { char myStrings[2][12]; char *newStrings[2]; strcpy(myStrings[0],"7/2/2010"); strcpy(myStrings[1],"hello"); newStrings[0]=myStrings[0]; newStrings[1]=myStrings[1]; fun(newStrings); return(0); } 

¿No es la matriz [2] [12] lo mismo que una matriz de punteros de caracteres cuando se pasa a una función?

Tratar

void fun(char s[][12]) { ...}

Lea también el c-faq: Mi comstackdor se quejó cuando pasé una matriz bidimensional a una función esperando un puntero a un puntero

No, la char array[2][12] es una matriz bidimensional (matriz de matrices). char *array[2] es una matriz de punteros.

char array[2][12] ve así:

 7/2/2010\0\x\x\xhello\0\x\x\x\x\x\x 

donde \ 0 es NUL y \ x es indeterminado.

mientras

char *array[2] es:

 0x CAFEBABEDEADBEEF 

(asumiendo 32 bits)

El primero tiene 24 caracteres contiguos, el segundo tiene dos punteros (a los principios de cadenas en otro lugar).

¿No es la matriz [2] [12] lo mismo que una matriz de punteros de caracteres cuando se pasa a una función?

No, es una matriz bidimensional. La diferencia es que una matriz de punteros contiene punteros, pero la array[2][12] es en realidad una matriz de matrices, sin punteros.

Por cierto que podrías hacer:

 char* mystrings[2]={"aha", "haha"}; fun(mystrings); 

char myStrings[2][12]; declara myStrings como una matriz de matrices de caracteres. Esto significa que myStrings se almacena como los 24 bytes.

 7/2/2010.???hello.?????? '——————————''——————————' myStrings[0]myStrings[1] 

donde representa un carácter nulo y ? Representa un byte no inicializado.

char *newStrings[2]; declara newStrings como una matriz de punteros a caracteres. Esto significa que newStrings se almacena como 2 × sizeof(char*) bytes

 [..][..] 

donde [..] representa un objeto puntero (aún no inicializado).

Si desea pasar cadenas de diferentes longitudes a su función, debe pasar una serie de punteros, no una matriz de matrices. Como puedes ver arriba, estos son diseños diferentes.

Consejo general: cuando esté cerca de punteros, dibuje diagtwigs (en la pizarra o pizarra, si puede, de lo contrario, en papel) que muestren los diversos objetos en la memoria, con flechas que indican lo que apunta a dónde. Hay dos tipos de progtwigdores en C: los que dibujan diagtwigs de este tipo cuando se encuentran con punteros y los realmente experimentados que dibujan los diagtwigs en su cabeza.

Su matriz se declara como una matriz 2-D, pero desea pasarla a la función como si fuera una matriz 1-D de punteros de cadena.

La respuesta de Tom es correcta, puede omitir el tamaño de la primera dimensión de las declaraciones de matrices multidimensionales para los parámetros de función.

Su segunda solución funciona porque pasa explícitamente una matriz 1-D de punteros de cadena a la función. Por supuesto, requiere la sobrecarga adicional de la matriz de punteros además de la matriz de cadenas 2-D original.