2010-05-12 13 views
5

gcc 4.4.3 c89descarga de pila acceso a la matriz de caracteres malloc

Tengo el siguiente código fuente. Y obteniendo un volcado de pila en el printf.

char **devices; 
devices = malloc(10 * sizeof(char*)); 

strcpy(devices[0], "smxxxx1"); 

printf("[ %s ]\n", devices[0]); /* Stack dump trying to print */ 

Estoy pensando que esto debería crear una matriz de caracteres como esta.

devices[0] 
devices[1] 
devices[2] 
devices[4] 
etc 

Y cada elemento que puedo almacenar mis cadenas.

Muchas gracias por todas las sugerencias,

== === corrección Añadido

for(i = 0; i < 10; i++) 
{ 
    devices[i] = malloc(strlen("smxxxx1")+1); 
} 
+1

Felicitaciones por una pregunta que provoca varias respuestas casi idénticas. – sum1stolemyname

+0

volcado de pila o volcado de núcleo? –

+0

@Matt Curtis: parece recordar que los programas generados por gcc para win32 generan volcados de pila en el cuadro dos en el que se ejecutaron cuando tenían algunos tipos de errores. Sin embargo, no parece hacer eso en mi configuración actual (mingw, vista, x86-32). – nategoose

Respuesta

5

Ha asignado memoria para una serie de punteros. Debe asignar la memoria para cada elemento para almacenar la cadena

por ej.

#define NUM_ELEMENTS 10 
char **devices; 
devices = malloc(NUM_ELEMENTS * sizeof(char*)); 

for (int i = 0; i < NUM_ELEMENTS; i++) 
{ 
    devices[i] = malloc(length_of string + 1); 
} 
+0

Introduce NUM_ELELENTS y ​​aún usa 10 en la llamada malloc(). – sharptooth

1

ha asignado espacio para los punteros (dispositivos), pero no han asignado espacio para las cadenas que se van a almacenar.

2

Solo ha asignado una matriz de punteros a las matrices de caracteres. Usted tendrá que asignar memoria para cada cadena tiene previsto almacenar: Memoria

char **devices; 
devices = malloc(10 * sizeof(char*)); 

//Added this line: 

devices[0] = (char*)malloc(strlen("smxxxx1")+1); 
strcpy(devices[0], "smxxxx1\0"); 

printf("[ %s ]\n", devices[0]); /* Stack dump trying to print */ 
+2

Sus cadenas realmente no necesitan incluir '\ 0' explícitamente, ya están terminadas nulas – Hasturkun

+0

Solo me lo pregunto como una precaución adicional. En caso de que la matriz de caracteres real sea NULL terminada. Tengo 10 elementos. Sin embargo, el 10 debe ser NULL. ¿Esto es en caso de que esté recorriendo la pantalla y quiera detenerse en NULL? Solo una idea Gracias. – ant2009

+1

@robUK: Usar NULL como un valor centinela al final de una matriz a veces es una práctica común (por ejemplo, 'argv'). Depende de la situación; a veces puede que no haya un valor apropiado que pueda usarse como un centinela (¿qué pasaría si NULL fuera un elemento legítimo en su matriz? ¿y si no tiene que lidiar con una serie de punteros?). – jamesdlin

3

Usted ha asignado para el almacenamiento de carbón 10 punteros. Para almacenar una cadena en esta ubicación de memoria, debe asignar memoria para cada uno de ellos. Básicamente necesita algo como device[0] = malloc(stringLen + 1); para cada puntero.

4

dispositivos [0] es un char *, pero no se han asignado ningún almacenamiento para ello. Qué esto en su lugar:

char **devices; 
devices = malloc(10 * sizeof(char*)); 

devices[0] = strdup("smxxxx1"); 

printf("[ %s ]\n", devices[0]); 

Eventualmente, usted tiene que liberar la memoria asignada por strdup():

free(devices[0]); 
0

dispositivos es una matriz de punteros. Está copiando la cadena "smxxxx1" sobre la matriz, cuando parece que desea establecer el elemento 0 para que apunte a la cadena.

En lugar de la strcpy() Probar:

devices[0] = "smxxxx1" 

o

devices[0] = strdup("smxxxx1") 

Editar:

En un sistema de 32 bits, los dispositivos de [0] está compuesto de cuatro bytes . Estos cuatro bytes se sobrescriben con los valores de bytes de los primeros cuatro caracteres de la cadena "smxxxx1". En ascii estos son 0x73, 0x6D, 0x78, 0x78. Suponiendo el direccionamiento little-endian, termina con dispositivos [0] que contienen un puntero a la dirección 0x78786D73. Esta dirección casi seguramente no será válida dentro del proceso. Cuando la llamada a printf() intenta desreferenciar este puntero no válido, el sistema operativo desencadena una falla de segmentación y vuelca el núcleo.

El problema fue que el OP estaba tratando incorrectamente la variable de los dispositivos como una cadena (matriz de caracteres) al inicializarla. Es realmente una matriz de punteros a char, y printf() lo interpreta como tal.

+0

Rechazaría esto si la matriz OP era de punteros a const. –

+0

Constness no es relevante. Es un concepto de lenguaje. El stackdump se desencadena por el SO. –

+0

Constness seguro es un concepto de lenguaje, pero prefiero que el compilador me impida escribir a través de un puntero a const que obtener una captura de kernel en tiempo de ejecución. –

Cuestiones relacionadas