Pasar matriz por referencia usando C

Sí, he leído esta pregunta y respuestas: ¿Pasar una matriz por referencia en C?. Tengo un problema similar e implementé la misma idea de esa pregunta.

Sin embargo, sigo recibiendo un error del siguiente código:

#include <iostream>

void FillArray(int** myArray)
{
   free( *myArray ) ;
   * myArray = (int*) malloc(sizeof(int) * 2);

   *myArray[0] = 1;
   *myArray[1] = 2;
}

int main()
{
   int* myArray = NULL;
   FillArray(& myArray);    
   return 0;
}

Recibí el siguiente error de tiempo de ejecución justo después de que finaliza la función FillArray:

Excepción no controlada en 0x773115de en Program.exe 0xC00000005: Ubicación de escritura de infracción de acceso 0xcccccccccc.

Estoy usando Visual Studio, abrí Visual C++ Empty Project. Y el archivo llamado main.cpp. ¿Significa eso que está compilado con el compilador C++ en lugar del compilador C? Si es así, ¿cómo puedo abrir un archivo que se compilará solo con el compilador C? Intenté cambiar el nombre de main.cpp con main.c, pero sigo teniendo el mismo problema. (Hago esta pregunta porque leí algo sobre "pasar por referencia" y vi que es diferente en C y C++).

Perdón por esta pregunta tan fundamental.

Seré apreciado por cualquier ayuda,

Sat.

preguntado el 03 de mayo de 12 a las 21:05

No existe tal cosa como una referencia en C... -

"Pasar por referencia" es solo una forma genérica de referirse a él. En C, el paso por referencia se implementa a través de punteros. Dale al chico un descanso. -

@EdS.: Pasar por referencia es una terminología de programación independiente del lenguaje. O quizás debería decir "informática". Ya sea que C tenga referencias similares a las de C++ o no, si alguien me preguntara si C tiene referencias pasadas, respondería que sí. -

@post_erasmus: Exactamente por qué debemos usar la terminología correcta :). En C, siempre estás pasando una copia. Si pasa un puntero, se hace una copia de dicho puntero y se pasa a la función. Ahora, ambos punteros apuntan a la misma ubicación de memoria, pero los punteros en sí son únicos.. Es por eso que esto funcionará según lo previsto. void foo(struct foo *p) { p->some_member = 1; } pero esto no lo hará void foo(struct foo *p) { p = malloc(sizeof(struct foo)); }. En este último caso sólo se modificará la copia. -

llamar por referencia y llamar por valor son modismos comunes en la programación. aunque no son términos técnicos puros (por ejemplo, algunos consideran que java pasa objetos por referencia, otros dicen que las referencias se pasan por valor), 'pasar por referencia' no significa necesariamente usar tipos de 'referencia' en C++. -

3 Respuestas

La precedencia no está funcionando como esperaba. Prueba estos:

(*myArray)[0] = 1;
(*myArray)[1] = 2;

(Nota: iostream no es C. Es C++.)

contestado el 03 de mayo de 12 a las 21:05

Su problema es uno de precedencia de operadores.

La [] El operador se une con más fuerza que el * operador, entonces

*myArray[1] 

es el mismo que

*(myArray[1]).  

Esto es incorrecto, ya que el puntero de nivel superior solo tiene suficiente memoria asignada para un puntero. Usted quiere:

(*myArray)[1] = 2;

En una nota al margen, no hay una buena razón para mezclar C y C ++ como lo ha hecho. Obviamente tienes código C++ aquí, así que prefiere new y delete encima malloc y free porque los dos últimos no tienen en cuenta los constructores y destructores de objetos complejos.

contestado el 03 de mayo de 12 a las 21:05

Entonces, el código tiene problemas, pero aquí hay una pista falsa: es perfectamente legal llamar gratis en un puntero NULL. (Como es de esperar, no hace nada). - shanef22

@shanef22: Eso es cierto, debería haberlo aclarado. - Ed s.

Si. Podría ser, quizás, una mala práctica; pero como dice @ shanef22, no cambió nada. Todavía tengo el mismo error. - Sait

@zagy: Escribí mi respuesta demasiado rápido, lo siento. En realidad, fue un poco más sutil, mira mi respuesta actualizada. - Ed s.

@EdS.: Lo siento, implementé la respuesta de junjanes primero. :) Gracias por tu respuesta y por ayudarme con la terminología también... - Sait

Bueno:

int main()
{
   int* myArray = NULL;
   FillArray(& myArray);   
   ...

Bueno:

void FillArray(int** myArray)
{
   * myArray = (int*) malloc(sizeof(int) * 2);

Catastróficamente malo:

void FillArray(int** myArray)
{
   free( *myArray ) ;
   * myArray = (int*) malloc(sizeof(int) * 2);
   ...

Mejor:

void FillArray (int** myArray)
{
   if (myArray)
     free (*myArray);
   *myArray = (int*) malloc(sizeof(int) * 2);
   ...

ADEMÁS:

   *(myArray[0]) = 1;
   *(myArray[1]) = 2;

contestado el 03 de mayo de 12 a las 21:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.