¿Cómo es posible que realloc no funcione pero malloc?

He llegado a un punto en el que realloc deja de devolver un puntero; supongo que falta espacio para que la matriz se expanda o se mueva. El único problema es que realmente necesito que exista esa memoria o la aplicación no se puede ejecutar como se esperaba, así que decidí probar malloc, esperando que no funcione ya que realloc no funcionaría, pero lo hizo. ¿Por qué?

Luego, puse en memoria la matriz de punteros en la nueva matriz asignada, pero descubrí que se rompió, se colocaron punteros como 0x10 y 0x2b en la matriz. Hay punteros reales, pero si reemplazo el memcpy con un bucle for, eso lo arregla. ¿Por qué Memcpy hizo eso? ¿No debería usar memcpy en mi código?

Código:

float * resizeArray_by(float *array, uint size)
{
    float *tmpArray = NULL;
    if (!array)
    {
        tmpArray = (float *)malloc(size);
    }
    else
    {
        tmpArray = (float *)realloc((void *)array, size);
    }

    if (!tmpArray)
    {
        tmpArray = (float *)malloc(size);
        if (tmpArray)
        {
            //memcpy(tmpArray, array, size - 1);
            for (int k = 0; k < size - 1; k++)
            {
                ((float**)tmpArray)[k] = ((float **)array)[k];
            }
            free(array);
        }
    }

    return tmpArray;
}

void incrementArray_andPosition(float **& array, uint &total, uint &position)
{
    uint prevTotal = total;
    float *tmpArray = NULL;
    position++;
    if (position >= total)
    {
        total = position;
        float *tmpArray = resizeArray_by((float *)array, total);
        if (tmpArray)
        {
            array = (float **)tmpArray;

            array[position - 1] = NULL;
        }
        else
        {
            position--;
            total = prevTotal;
        }
    }
}

void addArray_toArray_atPosition(float *add, uint size, float **& array, uint &total, uint &position)
{
    uint prevPosition = position;
    incrementArray_andPosition(array, total, position);

    if (position != prevPosition)
    {
        float *tmpArray = NULL;
        if (!array[position - 1] || mHasLengthChanged)
        {
            tmpArray = resizeArray_by(array[position - 1], size);
        }

        if (tmpArray)
        {
            memcpy(tmpArray, add, size);
            array[position - 1] = tmpArray;
        }
    }
}

Después de todas mis correcciones, el código probablemente esté en su lugar. Lo interesante aquí es que después de ordenar las matrices, asigno con malloc una matriz enorme, para reordenar las matrices en una matriz para usarla como GL_ARRAY_BUFFER. Si la reasignación no se asigna debido a la falta de espacio, ¿por qué no se asigna?

Finalmente, esto hace que se estrelle al final de todos modos. Después de pasar por la función de renderizado una vez que se bloquea. Si eliminé todas mis correcciones y descubrí cuando realloc no asigna, funcionaría bien. Lo que plantea la pregunta, ¿qué hay de malo en colocar mal mi matriz en lugar de reasignar para causar problemas más adelante?

Mis Array son punteros de punteros de flotadores. Cuando hago crecer la matriz, se convierte en un puntero a flotadores y se reasigna. Estoy construyendo en Android, por eso asumí que había falta de memoria.

preguntado el 10 de mayo de 11 a las 14:05

Es difícil entender cuál es el problema sin ver el código. ¿Podría incluir algo de contexto sobre el uso de memcpy? ¿Las llamadas realloc y malloc? -

Parece que hay un error en el trabajo aquí. Ya sea en su código o en el CRT (menos probable). -

¿Está confundiendo el significado de la variable 'tamaño'? ¿Es el tamaño de las matrices en bytes o el número de flotantes en la matriz? -

¿Por qué su pregunta está etiquetada como C y C ++ al mismo tiempo? -

@AndreyT porque estoy escribiendo C en C ++, debido a android-ndk -

3 Respuestas

Usted está confundiendo size y tipos de puntero. En la asignación de memoria, size es el número de bytes y está convirtiendo el tipo de puntero a float *, esencialmente creando una matriz de float de tamaño size / sizeof(float). En el código equivalente a memcpy, está tratando la matriz como float ** y copiando size de ellos. Esto destruirá el montón, asumiendo que sizeof(float *) > 1, y es probable que sea la fuente de problemas posteriores.

Además, si está copiando, digamos, una matriz de tamaño 100 en una matriz de tamaño 200, debe copiar más de 100 elementos, no 200. Copiar más allá del final de una matriz (que es lo que está haciendo) puede llevar para programar bloqueos.

Una matriz de punteros asignados dinámicamente a floats será de tipo float **no, float *, y ciertamente no una mezcla de los dos. El tamaño de la matriz es el número de bytes para malloc y amigos, y la cantidad de elementos en todas las operaciones de la matriz.

memcpy copiará fielmente bytes, asumiendo que los bloques de origen y destino no se superponen (y los bloques de memoria asignados por separado no lo hacen). Sin embargo, has especificado size - 1 para la cantidad de bytes copiados, cuando la cantidad copiada debe ser del tamaño de bytes exacto de la matriz anterior. (¿De dónde obtiene valores de puntero incorrectos de todos modos? Si está en la parte expandida de la matriz, está copiando basura allí de todos modos). memcpy te está dando tonterías, para empezar se está volviendo tonto, y no es tu problema.

contestado el 10 de mayo de 11 a las 19:05

Cuando imprimo los valores de la matriz memcpy memcpy(tmpArray, array, size - 1) Tengo los malos consejos. - NebulaFox

A juzgar por todos los diferentes bits de información (realloc no encontrar memoria, memcpy comportarse inesperadamente, se bloquea) esto suena mucho como una corrupción del montón. Sin algunas muestras de código de lo que está haciendo exactamente, es difícil decirlo con certeza, pero parece que está administrando mal la memoria en algún momento, lo que hace que el montón entre en un estado no válido.

¿Puede compilar su código en una plataforma alternativa como Linux (es posible que tenga que apuntar algunas API específicas de Android)? Si es así, puede ver lo que sucede en esa plataforma y / o usar valgrind para ayudar a encontrarlo.

Finalmente, como tiene este C ++ etiquetado, ¿por qué está usando malloc / realloc en lugar de, por ejemplo, vector (u otro recipiente estándar) o new?

contestado el 10 de mayo de 11 a las 19:05

En android-ndk, la biblioteca estándar no existe. Originalmente usé vector. Y como no hay una reasignación en C ++, escribo en C. - NebulaFox

Y por cierto, no necesitas probar si array is NULL

Puedes reemplazar

if (!array)
{
    tmpArray = (float *)malloc(size);
}
else
{
    tmpArray = (float *)realloc((void *)array, size);
}

by

tmpArray = realloc(array, size*sizeof (float));

realloc actúa como malloc cuando se le da un NULLpuntero.

Otra cosa, tenga cuidado de que el tamaño no sea 0, ya que reasignar con 0 como tamaño es lo mismo que free.

Tercer punto, haz no encasillado punteros cuando no es estrictamente necesario. Escribió el retorno de las funciones de asignación, se considera una mala práctica desde ANSI-C. Es obligatorio en C ++, pero como estás usando la asignación de C, obviamente no estás en C ++ (en ese caso deberías usar new/delete). La conversión de la variable de matriz a (void *) tampoco es necesaria, ya que podría ocultar algunas advertencias si su parámetro se declaró falsamente (podría ser un int o un puntero a un puntero y, al emitir, habría suprimido la advertencia).

contestado el 10 de mayo de 11 a las 21:05

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