2011-06-17 12 views

Respuesta

23

matrices se descomponen o se convierten implícitamente a los punteros cuando se pasa a una función como un argumento, o cuando se convierte en un R- valor en el lado derecho del operador de asignación. Así que algo como:

int array[10]; 
int* a = array; //implicit conversion to pointer to type int 

void function(int* a); 
function(array); //implicit conversion to pointer to type int 

funciona muy bien. Pero eso no significa que las matrices en sí mismas son punteros. Por lo tanto, si trata una matriz como un puntero como lo hizo, en realidad está tratando el tipo de matriz como si fuera un puntero que tuviera la dirección en un objeto int. Como su matriz es en realidad una secuencia de objetos int, y no apunta a objetos int, en realidad está intentando desreferenciar a alguna ubicación de memoria que no apunta a ningún lugar válido (es decir, la primera ranura en array es un valor numérico entero como 0 que sería como desreferenciar un NULL). Entonces es por eso que estás segfaulting. Tenga en cuenta que si hubiera hecho algo como esto:

int array[] = { 1, 2, 3, 4, 5}; 
int b = *array; 

que todavía funciona, ya que array está de nuevo implícitamente convertido a un puntero al bloque de memoria que tenga una secuencia de valores enteros y luego se eliminan las referencias para obtener el valor en la primera secuencia Pero en su caso, al declarar su matriz al módulo de código actual como un puntero definido externamente, y no como una matriz, omitirá la conversión implícita a un puntero que normalmente está hecho, y simplemente usará el objeto de la matriz como si eran un puntero a un objeto en sí mismo, no una matriz de objetos.

+0

¿alguna sugerencia sobre dónde podría leer más sobre este comportamiento? – estebro

+2

Miro la salida del compilador para ver este comportamiento, es bastante evidente si está familiarizado con el lenguaje de ensamblaje básico para su plataforma. Verá que la referencia de matriz realmente está siendo tratada de la misma manera por la máquina como si fuera un acceso de puntero. [Esta pregunta aquí] (http://stackoverflow.com/questions/1461432/what-is-array-decaying) también puede proporcionar cierta ayuda. – Jason

+0

Gracias por la información adicional (y por volver a una pregunta tan antigua). – estebro

15

Bien explicado en el C FAQ. Y hay a followup. La imagen en el segundo enlace vale un millón de dólares.

char a[] = "hello"; 
char *p = "world"; 

enter image description here

Respuesta corta: uso extern int a[].

0

Básicamente lo que se necesita para escribir su main.c así:

extern int a[]; 

int main() 
{ 
    printf("%d\n", a[0]); 
    return 0; 
} 
2

Un poco tarde, un duplicado de este problema acaba de entrar (y se cerró). Las respuestas aquí no mencionan archivos de encabezado ...

El problema se detectaría en tiempo de compilación si coloca la declaración de matriz a en un archivo de encabezado, donde pertenece, en lugar de colocarlo en el archivo .c . El archivo de encabezado debe incluirse en ambos archivos .c y el compilador puede ver que lo que ha declarado es incorrecto.

Su archivo de cabecera contendría:

extern int myarray[]; 

Usted recibirá algo así como "error: conflicting types for a" si se declara a como un puntero en su lugar.

0

Consulte la salida del siguiente código.

Archivo1.c

#include <stdio.h> 

extern int* my_arr; 

void my_print() 
{ 
    printf("%d", my_arr); 
} 

main.c

#include <stdio.h> 

int my_arr[2] = {1,2}; 

extern void my_print(); 

void main() 
{ 
    my_print(); 
} 

salida

1 

dentro Archivo1.c my_arr es una variable puntero que tiene el valor de 1. es decir, el El primer elemento de my_arr [] se le asignó. Entonces, si usa * my_arr para acceder a la ubicación de la memoria ox1, obtendrá seg fault porque no tiene permitido acceder a ox01.

¿Por qué my_arr puntero fue asignado 1 (el primer elemento de my_arr [])?

Tiene que ver con cómo funciona el ensamblador. Lea this article

¿Por qué su código no puede acceder a 0x01?

Sé que tiene que ver con el sistema operativo que no permite que se acceda a un espacio de direcciones por código de usuario. Eso es todo lo que sé. google si quieres más información.