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

Cambiar Array de tamaño y contenido

Estas en el tema de Cambiar Array de tamaño y contenido en el foro de C/C++ en Foros del Web. Hola, estoy iniciando en Android y me tope con una aplicación que tiene algunas funciones y Arrays escritos en C/C++, no se C/C++, estaba leyendo ...
  #1 (permalink)  
Antiguo 18/10/2012, 22:00
 
Fecha de Ingreso: octubre-2011
Mensajes: 27
Antigüedad: 12 años, 6 meses
Puntos: 2
Cambiar Array de tamaño y contenido

Hola, estoy iniciando en Android y me tope con una aplicación que tiene algunas funciones y Arrays escritos en C/C++, no se C/C++, estaba leyendo algunos tutoriales y algunas referencias y no se me hace tan complicado pero me parece que lo intento hacer es algo avanzado, el asunto es este:

Tengo un Array escrito en C/C++ de esta forma

Código:
float arrayFl1 [] = {
  0.172, -0.0717, 0.2285,
  0.176, -0.068, 0.228
}
estaba buscando como cambiar sus valores mas o menos así:

Código:
arrayFl1 = nuevoArray;
en C/C++ no funciona, a menos que sean del mismo tamaño, en dado caso se usaría un for, creo, mi duda sería, como cambio el arrayFl1 por un Array de diferente tamaño, esta de sobra, pero el Array nuevo proviene de Java, por medio de una función en C/C++ lo recibo, este Array es diferente en valores y tamaño

Parece que los Arrays dinámicos o punteros en C/C++, son los que se pueden cambiar de tamaño, intente rescribir el Array así

Código:
float arrayFl1 [] = {
  0.172, -0.0717, 0.2285,
  0.176, -0.068, 0.228
}

float *arrayFl1D;

arrayFl1D = arrayFl1;
y así:

Código:
float *arrayFl1 [] = {
  0.172, -0.0717, 0.2285,
  0.176, -0.068, 0.228
}
pero el compilador me dio error.

¿Alguna idea de como cambiar un Array por otro de diferente tamaño y valores?

Saludos!
  #2 (permalink)  
Antiguo 19/10/2012, 04:31
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Cambiar Array de tamaño y contenido

La primera forma que has probado es la correcta, excepto que olvidaste el ; que va al final de la declaracion de arrayFl1; ten en cuenta que los dos siguientes codigos declaran la misma cosa:

Código:
//este es el que has colgado
float arrayFl1[] = {
        0.172, -0.0717, 0.2285,
        0.176, -0.068, 0.228
};

//y equivale a lo siguiente
float *arrayFl1;
arrayFl1 = malloc(6*sizeof(float));
arrayFl1[0] = 0.172;
arrayFl1[1] = -0.0717;
arrayFl1[2] etc hasta llenar la lista
//en este caso al final tienes que liberar la memoria con free(arrayFl1);

//y ahora asignas
float *arrayFl1D = arrayFl1;
Con la segunda forma de declarar la lista ves claramente que es una asignacion por referencia; puedes hacer la prueba mostrando cualquier elemento.

Una otra cosa, acostumbra a no usar nombres tan parecidos o en caso inevitable usa prefijos que diferencien claramente los nombres de variables, te ahorrará problemas a ti y a cualquiera que pudiese ver tu codigo.

Saludos
vosk
  #3 (permalink)  
Antiguo 19/10/2012, 11:31
 
Fecha de Ingreso: octubre-2011
Mensajes: 27
Antigüedad: 12 años, 6 meses
Puntos: 2
Respuesta: Cambiar Array de tamaño y contenido

Gracias vosk por contestar y por el tip, solo que me sigue quedando la duda como agrego mas elementos al puntero, intente con:

Cita:
float arrayFl1[] = {
0.172, -0.0717, 0.2285,
0.176, -0.068, 0.228
};

float *arrayFl1D = arrayFl1;

//Despues

arrayFl1D[6] = 0.275;
y aunque si lo compila, en tiempo de ejecución se tarda mucho y luego se cierra, imagino que es porque el array tiene 6 elementos.

Saludos!
  #4 (permalink)  
Antiguo 19/10/2012, 15:28
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Cambiar Array de tamaño y contenido

Ok, perdona no habia entendido tu duda;

Tienes que relocalizar la memoria de tu lista para adaptarla al nuevo numero de elementos (es igual añadir elementos que quitarlos), en cualquier caso no mezcles tipos (si tienes una lista de int no esperes relocalizar la memoria con tipos float si quieres conservar los datos antiguos, si quieres olvidarte de ellos y generar una lista nueva no hay problema en relocalizar memoria para diferentes tipos).

Antes de nada ten en cuenta que la declaracion que usas 'float variable[] = {1,2,3};' crea una especie de variable dinamica controlada por la aplicacion, es decir que al finalizar se encarga la aplicacion de eliminar la memoria bloqueada para esa variable. En el caso que te ocupa, ya que vas a relocalizar memoria no te interesa que la aplicacion se encargue de liberarla, asi evitas los memory leaks o como se llame (los s.o. actuales recuperan esa memoria al finalizar el proceso de la aplicacion, pero ya que se hace es mejor hacerlo bien).

Para ello tendras que hacerlo tal como colgué en mi post anterior, con un malloc y una longitud. Aquí entra otra variable que tendras que arrastrarla durante toda la aplicacion: necesitas algo que guarde el numero de elementos (puedes hacerlo hardcoded, pero no es elegante), de forma que deberas comenzar con algo asi:

Código:
    float *arrayFl1, *ptr;
    int elementos, q;
    
    elementos = 6;
    arrayFl1 = malloc(elementos*sizeof(float));
    arrayFl1[0] = 0.172;
    arrayFl1[1] = -0.0717;
    arrayFl1[2] = 0.2285;
    arrayFl1[3] = 0.176;
    arrayFl1[4] = -0.068;
    arrayFl1[5] = 0.228;
    
    ptr = arrayFl1;
Ahora tienes la lista en dos punteros que a efectos finales son completamente identicos, cualquier cosa que modifiques sobre 'arrayFl1' se modificará tambien para 'ptr' y lo mismo del revés, porque realmente ambos son punteros a un mismo bloque de memoria; de forma que segun mi parecer uno de los dos sobra, no tiene ninguna ventaja tener los dos ok?

Ahora viene lo que te interesa, como expandes la lista? Primero declaras una nueva variable donde guardarás el resultado de la relocalizacion de memoria (puedes declararla junto con las otros float* porque será del mismo tipo, luego incrementas el contador de elementos, haces un realloc de la lista (cualquier de los dos punteros sirve como puntero al bloque de memoria) asignando el retorno al nuevo puntero, luego asignas a 'arrayFl1' el nuevo puntero y ya puedes añadir el nuevo elemento, algo asi:

Código:
    //declaras arriba la nueva variable
    float *arrayFl1, *ptr, *mem;

    elementos++;
    mem = realloc(arrayFl1, sizeof(float)*elementos);
    arrayFl1 = mem;
    arrayFl1[elementos-1] = 1.2345;
Ya tienes una lista de 7 elementos. Recuerda que al finalizar tienes que liberar el bloque de memoria con 'free(arrayFl1);'

A lo mejor te estas preguntando por que usar una nueva variable *mem para la relocalizacion si puedes asignar directamente el resultado al puntero antiguo?

Código:
    arrayFl1 = realloc(arrayFl1, sizeof(float)*elementos);
Solo hay un caso en que eso no es bueno hacer, y es como siempre el caso de error: si realloc retorna NULL no podras llamar a free para liberar el bloque de arrayFl1, por eso se asigna a un puntero 'de asistencia' y las comprovaciones de error se hacen sobre ese:

Código:
    if(!(mem = realloc(arrayFl1, sizeof(float)*elementos))) {
        //condicion de error, libera arrayFl1 y finaliza aplicacion
    }
Ten en cuenta que aunque no asignes el nuevo bloque relocalizado al viejo puntero es posible que desde el viejo puedes trabajar con el nuevo como si nada, pero esto solo es una casualidad que se puede dar a causa de la localizacion del nuevo bloque de memoria, pero no es lo normal ni lo correcto, siempre debes reasignar el bloque relocalizado al puntero que estabas usando; cuando se hace la relocalizacion si no se puede ampliar el bloque antiguo, se crea uno de nuevo ampliado y se libera el viejo, por eso solo es necesario un free al final para liberar cualquier relocalizacion que hayas echo.

Y otra cosa, lo mismo se aplica para quitar elementos; pero ten siempre presente que el numero de elmentos por si solo no indica nada, tiene que multiplicarse por el tamaño del tipo que estas usando o de lo contrario podría tener resultados no esperados. Si quieres quitar el ultimo elemento simplemente decrimentas el contador y relocalizas de nuevo, automaticamente el ultimo elemento queda fuera de la lista. Para quitar elementos intermedios primero tendras que usar algun truco o llamalo algoritmo para mover los elementos posteriores al elemento objetivo hasta dejarlos en la posicion de su elemento anterior, de forma que te quedará una ultima posicion eliminable, relocalizas la memoria y ya lo tienes.

Saludos
vosk
  #5 (permalink)  
Antiguo 03/11/2012, 16:33
 
Fecha de Ingreso: octubre-2011
Mensajes: 27
Antigüedad: 12 años, 6 meses
Puntos: 2
Respuesta: Cambiar Array de tamaño y contenido

Excelente!, muchas gracias, me sirvió de maravilla, aunque al liberar memoria me modificaba los valores del Array por ahora no pienso darle mucha importancia a ese detalle.

Saludos!

Etiquetas: compilador, contenido, tamaño
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 00:26.