Hola! Es una tontería pero ahora mismo no lo recuerdo bien. En un main declaro una serie de variables que le paso como parámetro a una función void. La función void efectúa cambios sobre estas variables pero sin embargo, al ir a seguir "jugando" con ellas en el main no tienen el valor modificado, si no que tienen el original. ¿Cómo soluciono esto?
tienes que pasar el puntero:
//Declaramos la función, con dos punteros como variables
void funcionMia(int *a, int *b);
//main function
main(){
int hola, adios;
funcionMia(*hola, *adios)
}
void funcionMia(int *a, int *b){
&a=1+8;
&b=a-4;
}
era algo así, no?
si no me falla la memoria, le pasas la direccion de a y de b (por eso *a y *b) y en la función como esas variables son direcciones de memoria, le ponemos el "&" delante para decir "Donde apunta la dirección de 'a' escribe esto"
si ,creo que esta bien, se llama pasar por referencia o por valor si quieres mantener el valor o no..
Me parece que es al reves, es decir en la llamada a la funcion le pasas la direccion de la variable (&) y dentro de la funcion para cambiar el contenido es con el operador *.
//Declaramos la función, con dos punteros como variables
void funcionMia(int *a, int *b);
//main function
main(){
int hola, adios;
funcionMia(&hola, &adios)
}
void funcionMia(int *a, int *b){
*a=1+8;
*b=*a-4; //el contenido (*) de b será el contenido de a menos 4.
}
Otra opcion seria declarar las variables como punteros (int* hola, *adios) , con lo que lo único que variaría sería que la llamada a la funcion sería funcionMia(hola,adios) pero luego el acceso al contenido sería igual (con el *)
PD: Corregidme si me equivoco
si es ANSI C es exactamente como ha puesto #5
para los mas puros, en su código no ha inicializado ni hola ni adios, así que tendrán basura en ANSI C, hay que inicializarlos antes. Y el main le falta un void delante xD
Me sigo sin funcionar... En el main hago la llamada así (una variable entero y un puntero de carácteres, que por cierto, no se si se hará de la misma manera...)
lee_texto(&length, texto);
Como véis, en texto no le pongo nada porque ya es un puntero de chars.
Y la en la función:
void lee_texto(int * length, char * texto){
/* Declaramos variables y auxiliares */
int i = 0, j = 0, size = 100;
char aux;
/* Abrimos el archivo donde se encuentra el texto cifrado */
FILE *f;
f = fopen("archivodetexto.txt", "r");
if(f==NULL){
perror("No se puede abrir el archivo. Saliendo del programa!");
exit(1);
}
/* Reservamos memoria para el vector texto */
texto = (char *)malloc( size*sizeof(char) );
/* Leemos los caracteres del archivo (todos) */
*length = -1;
while(aux!=EOF){
aux = getc(f);
if(i>=100){
texto = (char *)realloc( texto, size++ );
}
texto[i] = aux;
i++;
*length++; // Indica la longitud del vector de texto
}
printf("%d\n", length);
}
O sea, lo que me falla es únicamente el vector
Saludos.
Te comento fallos que cometes, delegas que el vector te lo reserve una función para luego retornarlo, esto está mal.
/* Reservamos memoria para el vector texto */
texto = (char *)malloc( size*sizeof(char) );
el malloc tienes que hacerlo en la función que llama a lee_texto, si lee_texto descubre que necesita 25 MB de espacio para texto, debería retornar un error y en length poner la longitud necesaria y tu desde la otra función, hacer el malloc y volver a llamar, por qué ?
Primero, por que para que te funcione un malloc dentro de una función que pasas como parámetro un puntero, tienes que pasar un doble puntero, por que lo que haces es, la dirección a la que apunta el vector que pasas le generas una nuevo espacio en memoria que apuntará a la pila actual, no a la posición de memoria que tiene la función anterior, si has estudiado ensamblador entenderás que te estoy diciendo.
Si lo quieres seguir haciendo así, craso error, utiliza char ** texto en la llamada.
EDITO: ahora sigo escribiendo xD
tu cabecera quedará así:
void lee_texto(int * length, char ** texto){
Por otro lado y aunque me repita, o no, llevo muchos edits, nunca tienes que delegar a una función que reserve memoria por ti, pongamos que lee_texto está en un servidor o es una llamada de un webservice que trabaja en memoria en Big Endian, y tu trabajas en tu ordenador en little endian, si delegas la responsabilidad al webservice cuando retomes el resultado lo leerás mal y tendrás que reformatearlo.
Además, ponte que trabajas en la misma máquina, y esa llamada la tiene una DLL del sistema o un .SO, si la .DLL o el .SO o le .dylib, no nos vamos a poner quisquillosos xD reserva memoria, la está reservando en su zona de trabajo, ahora te hago la pregunta, quien debe liberarla ? tu aplicación que no tiene acceso real a esa zona o el .SO, .DLL o .DYLIB ?
Mi consejo es el siguiente.
char * texto = NULL;
int length = 0;
lee_texto(&length, texto);
texto = (char *)calloc(length,sizeof(char));
lee_texto(&length, texto);
Así la memoria la utilizas tú, quizá en un futuro cambias la aplicación de lugar o los sistemas operativos cambian su modus operandi y tu aplicación seguirá funcionando igual
Ah, y queda claro que tú problema es por no poner en la llamada de la función char ** texto
Pero es que si la función la declaro así:
void lee_texto(int * length, char **texto)
después me peta con los malloc xD
Otra preguntita:
Tengo declarado el siguiente vector:
char *buffer[]={"palabr", "palabra"};
Y tengo la siguiente función:
char* strgen(int i, char string[]){
char aux[6];
int j;
for(j=i;j<i+6;j++){
aux[j-i]=string[j];
}
return aux;
}
Y desde el main, hago la siguiente llamada:
buffer[0] = strgen(i, string);
Donde i es un iterador. Pero al compilar, aparece el siguiente chachi-error:
main.c: En la función ‘main’:
main.c:46: aviso: la asignación crea un puntero desde un entero sin una conversión
op.c: En la función ‘strgen’:
op.c:63: aviso: la devolución crea un entero desde un puntero sin una conversión
op.c:63: aviso: la función devuelve la dirección de una variable local