Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Duda: Contar elementos vector dentro de función.

Estas en el tema de Duda: Contar elementos vector dentro de función. en el foro de C/C++ en Foros del Web. Hola buenas, el objetivo de la función operar con un vector(tamaño l) y un entero(k), que son los datos recibidos, y devolver un vector (tamaño ...
  #1 (permalink)  
Antiguo 30/03/2016, 05:00
 
Fecha de Ingreso: marzo-2016
Mensajes: 3
Antigüedad: 8 años, 7 meses
Puntos: 0
Duda: Contar elementos vector dentro de función.

Hola buenas, el objetivo de la función operar con un vector(tamaño l) y un entero(k), que son los datos recibidos, y devolver un vector (tamaño l*k-k).
El caso es que para crear el nuevo vector y asignarle memoria necesito saber el tamaño del vector inicial y no se como poder recorrerlo para ir contándolo dentro de la función.
Por otra parte, al usar dentro de la función malloc(), ¿La memoria asignada hay que liberarla con free() en algún momento?.
Se supone que el programa pedirá introducir un vector sin especificar tamaño por lo que no se conocerá el tamaño.
Introduciendo un valor en longv1 parece que el programa funciona.
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. double *operaVector(int k, double *vector1);
  5.  
  6. int main(){
  7.     int i, k, longv2;
  8.     double vector1[]={3,2,5,4}, *vector2;
  9.     printf("Introduce el valor de k: ");
  10.     scanf("%d",&k);
  11.     longv2=longv1*k-k;
  12.     vector2=operaVector(k,vector1);
  13.     for(i=0;i<longv2;i++)
  14.     printf("El elemento numero %d del nuevo vector es: %lf\n",i+1,*(vector2+i));
  15.     return 0;
  16. }
  17.  
  18. double *operaVector(int k, double *vector1){
  19.     int i, longv2;
  20.     longv2=longv1*k-k;
  21.     double *vector2=malloc(longv2*sizeof(double));
  22.     if (vector2==NULL){
  23.         puts("Error reservando memoria");
  24.         exit(EXIT_FAILURE);
  25.     }
  26.     for(i=0;i<longv2;i++)
  27.         *(vector2+i)=*(vector1+i)*0.5+i;
  28.     return vector2;
  29. }
Espero que alguien me pueda ayudar, soy nuevo en el lenguaje C.
  #2 (permalink)  
Antiguo 30/03/2016, 05:11
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Duda: Contar elementos vector dentro de función.

La única forma es que la función acepte un nuevo parámetro que indique el tamaño del vector actual.

Por supuesto, sería recomendable conocer también el tamaño del nuevo vector por si tienes que ampliar su capacidad más adelante. En tal caso puede ser recomendable que este parámetro que estamos comentando se pase por referencia, de tal forma que en dicha variable se almacene el tamaño del nuevo array:

Entonces la primera llamada quedaría tal que:

Código C:
Ver original
  1. double *operaVector(int k, double *vector1, size_t* vectorSize);
  2.  
  3. int main(){
  4.     double vector1[]={3,2,5,4}, *vector2;
  5.     size_t vectorSize = sizeof(vector1)/sizeof(double); // 4 en la práctica
  6.  
  7.     vector2 = operaVector(k,vector1,&vectorSize);
  8. }
  9.  
  10. double *operaVector(int k, double *vector1,size_t* vectorSize){
  11.     int i, longv2;
  12.     // ...
  13.     *vectorSize = longv2;
  14.     return vector2;
  15. }

Una vez dicho esto te comento que si usas memoria dinámica lo suyo es liberarla después. Haces uso de malloc pero no veo ningún free. Quizás la función operaVector debería liberar la memoria asociada a vector1. Esta opción es una de las más limpias pero entonces no le puedes pasar un arreglo que no haya sido creado con malloc.

En cualquier caso, lo dicho, libera la memoria que reservas una vez ya no vaya a ser necesaria.

PD.: también existe realloc, que realiza todo el proceso por tí: reserva un área de memoria del tamaño indicado, copia los datos de la memoria antigua a la actual y finalmente libera la memoria antigua.

Un saludo
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #3 (permalink)  
Antiguo 30/03/2016, 08:06
 
Fecha de Ingreso: marzo-2016
Mensajes: 3
Antigüedad: 8 años, 7 meses
Puntos: 0
Respuesta: Duda: Contar elementos vector dentro de función.

Muchas gracias por la respuesta.

Respecto al uso del free, no veo muy bien donde situarlo, porque la memoria que se reserva es para el vector2 y lo que devuelve la función es el vector2. Por tanto, ¿Se debe liberar después de usarla en el programa usando free(vector2)?

Por último, ¿En lugar de size_t vectorSize se podría usar de igual manera int vectorSize?
  #4 (permalink)  
Antiguo 30/03/2016, 08:41
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Duda: Contar elementos vector dentro de función.

Cita:
Iniciado por Casert Ver Mensaje
Respecto al uso del free, no veo muy bien donde situarlo, porque la memoria que se reserva es para el vector2 y lo que devuelve la función es el vector2. Por tanto, ¿Se debe liberar después de usarla en el programa usando free(vector2)?
Imagina que vas a una bollería y te compras un bollo y te lo dan con una servilleta para que no te manches. Te vas de la bollería y te comes el bollo en el parque.... ¿En qué momento de esta historia tiras el papel a la basura?

Vale, ahora imagina que la bollería es la función operaVector, el papel es la memoria dinámica y el bollo los datos almacenados en dicha memoria.

Espero que la respuesta a la pregunta del papel sea que lo tiras una vez que te has comido el bollo, es decir, una vez que ya no necesitas los datos que están almacenados en la memoria te la cargas porque ya no la necesitas.

Se que es un ejemplo tonto pero creo que cambiando la perspectiva se consigue que problemas complicados parezcan bastante sencillos y lógicos.

Y bueno, por si no ha quedado del todo claro, la memoria la puedes borrar en cualquier momento, no tiene que ser necesariamente en la misma función que reservó dicha memoria. Más que nada piensa que a la memoria dinámica se accede desde punteros. free te pide un puntero y libera la memoria apuntada por el mismo... le da igual en qué momento fué creada y, entre otras cosas, solo con un puntero es imposible obtener esa información.

Cita:
Iniciado por Casert Ver Mensaje
Por último, ¿En lugar de size_t vectorSize se podría usar de igual manera int vectorSize?
Te pego un párrafo de la documentación de la MSDN (por eso de que está en español)

Cita:
El operando es un identificador que es un elemento unary-expression o una expresión de conversión de tipo (es decir, un especificador de tipo incluido entre paréntesis).El elemento unary-expression no puede representar un objeto de campo de bits, un tipo incompleto ni un designador de función.El resultado es una constante entera sin signo.El encabezado estándar STDDEF.H define este tipo como size_t.
Es decir, esa función te va a devolver siempre un valor con el tipo size_t. ¿Y qué narices es size_t? Pues es un alias. Uno de tantos que pululan por la librería de C.

¿Y por qué usar un alias? Como bien sabes (o deberías saber), los tipos numéricos en C no tienen un tamaño fijo sino que dependen de la arquitectura. Esto hace que escribir programas multiplataforma sea un auténtico dolor de cabeza ya que los rangos de valores cambiarán de una plataforma a otra.

Usar alias permite que el programador se pueda olvidar por unos momentos de ese problema. Ya que el alias no es un tipo fijo se puede cambiar fácilmente entre plataformas con algo tan tonto como esto:

Código C:
Ver original
  1. // Prueba a comentar estos defines de forma alternativa
  2. // compila y compara la salida del programa
  3. #define SISTEMA1
  4. //#define SISTEMA2
  5. //#define SISTEMA3
  6.  
  7. #ifdef SISTEMA1
  8. typedef int miTipo;
  9. #elif SISTEMA2
  10. typedef double miTipo;
  11. #else
  12. typedef char miTipo;
  13. #endif
  14.  
  15. int main()
  16. {
  17.   printf("%d",sizeof(miTipo));
  18. }

Por cierto, los propios compiladores suelen traer un juego de constantes ya definidas que indican ciertas características.

Dicho todo esto y para responder a tu pregunta:

Sí podrías, pero tu programa podría dar problemas en entornos multiplataforma. Otro problema que podrías tener (aunque sería raro de narices) es que el tamaño del objeto no entrase en un int pero sí en un "unsigned int", en ese caso obtendrías un resultado negativo y el programa se volvería errático.

Pero vamos que sin llegar a ser paranóicos te diría que sí, puedes usarlo... pero recuerda que puede dar problemas y, por tanto, no es una buena práctica a adquirir.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #5 (permalink)  
Antiguo 30/03/2016, 09:09
 
Fecha de Ingreso: marzo-2016
Mensajes: 3
Antigüedad: 8 años, 7 meses
Puntos: 0
Respuesta: Duda: Contar elementos vector dentro de función.

No tenía muy claro si el uso de free se podía hacer fuera de la función con malloc y me ha quedado claro. Buen ejemplo aclarativo

Muchas gracias. He podido solucionar y comprender los errores.

Etiquetas: elementos, funcion, int, lenguaje, numero, programa, vector
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:31.