Descargar

Apuntadores y Asignación Dinámica de Memoria

Enviado por Pablo Turmero


Partes: 1, 2, 3

    edu.red Almacenamiento en memoria La memoria puede verse como un conjunto de celdas numeradas y ordenadas, cada una de las cuales puede almacenar un byte de información. El número correspondiente a cada celda se conoce como su dirección.

    Cuando se crea una variable, el compilador reserva el número suficiente de celdas de memoria (bytes) requeridos para almacenar la variable, y se encarga de que los espacios reservados no se traslapen.

    edu.red Direcciones de memoria En C/C++ es posible obtener la dirección de memoria donde se encuentra almacenada una variable mediante el operador de referencia &

    Ejemplo:int main() { int a = 10, b = 20; cout << &a << endl; cout << &b << endl; return 0;}

    edu.red Tamaño de una variable Podemos también obtener la cantidad de memoria que ocupa una variable (en bytes) mediante el operador sizeof:int main() { int a = 10; cout << “Valor de a: “ << a << endl; cout << “Dirección de a: “ << &a << endl; cout << “Tamaño de a: “ << sizeof(a) << endl; return 0;}

    edu.red Apuntadores Un apuntador es una variable que contiene una dirección de memoria (donde posiblemente se almacene el valor de otra variable).

    Para crear apuntadores, se utiliza el operador * como se muestra a continuación:int main() { int a = 10; int *p; p = &a; cout << “Valor de p: “ << p << endl; cout << “Valor en p: “ << *p << endl; cout << “Dirección de p: “ << &p << endl;}

    edu.red Apuntadores Un apuntador es una variable que contiene una dirección de memoria (donde posiblemente se almacene el valor de otra variable).

    Para crear apuntadores, se utiliza el operador * como se muestra a continuación:int main() { int a = 10; int *p; p = &a; cout << “Valor de p: “ << p << endl; cout << “Valor en p: “ << *p << endl; cout << “Dirección de p: “ << &p << endl;} La variable p es de tipo “apuntador a int”

    edu.red Almacenamiento de arreglos Cuando se declara un arreglo, se reserva un solo bloque contiguo de memoria para almacenar todos sus elementos, y éstos se almacenan en la memoria en el mismo orden que ocupan en el arreglo:

    int main() { int i, a[10]; for (i = 0; i < 10; i++) { cout << &a[i] << endl; } return 0; }

    edu.red Almacenamiento de arreglos Cuando se declara un arreglo, se reserva un solo bloque contiguo de memoria para almacenar todos sus elementos, y éstos se almacenan en la memoria en el mismo orden que ocupan en el arreglo:

    int main() { int i, a[10]; for (i = 0; i < 10; i++) { cout << &a[i] << endl; } return 0; } Verificar que &a[i] es igual a &a[0] + i * sizeof(int)

    edu.red Arreglos y apuntadores En C/C++, el nombre de un arreglo es también un apuntador al primer elemento del arreglo.

    De hecho, el lenguaje C no puede distinguir entre un arreglo y un apuntador: ambos son completamente intercambiables.

    int main() { int i, a[10], *p;

    for (i = 0; i < 10; i++) { a[i] = i; }; p = a; for (i = 0; i < 10; i++) { cout << p[i] << endl; }

    return 0; }

    edu.red Aritmética de apuntadores Recuerde que un apuntador siempre está asociado con el tipo de dato al que apunta (e.g., apuntador a int, apuntador a float, etc).

    Esto hace posible definir la operación p+k donde p es un apuntador y k es un entero. El resultado de esta operación es

    p + k * sizeof(tipo) donde tipo es el tipo de datos asociado a p.

    Notar entonces que, si p es un arreglo

    &p[k] es equivalente a p+k y p[k] equivale a *(p+k)

    edu.red Ejemplo: operaciones elementales void MulRen(float *m, int n, int r, float k) { float *p = m + r * n; for (int j = 0; j < n; j++) { p[j] *= k; } }

    void SumRen(float *m, int n, int r1, int r2, float k) { float *p1 = m + r1 * n; float *p2 = m + r2 * n; for (int j = 0; j < n; j++) { p1[j] += p2[j] * k; } }

    void InterRen(float *m, int n, int r1, int r2) { float t; float *p1 = m + r1 * n; float *p2 = m + r2 * n; for (int j = 0; j < n; j++) { t = p1[j]; p1[j] = p2[j]; p2[j] = t; } }

    Partes: 1, 2, 3
    Página siguiente