2011-05-11 18 views
5

Poco a poco me estoy acostumbrando a los punteros. Pero todavía hay algunas preguntas que tengo.C Pregunta para principiantes: Aritmética del puntero> limpiar una vez que haya terminado

¿Es posible causar pérdidas de memoria al usar la aritmética del puntero porque está desplazando la posición real de hacia dónde apunta el puntero?

Quiero decir, si digo que cuento hacia arriba para copiar una cadena char por char, ¿necesitaría hacer una cuenta regresiva para que C "sepa" dónde apuntaba el puntero?

Gracias fugas Frank

+2

Sí (aunque es probable que va a ir * * BANG, en lugar de perder memoria) ... el puntero tiene que apuntar al inicio del bloque cuando se llama gratis – forsvarir

+2

Solo importa si el puntero fue el resultado de una llamada 'malloc'.Normalmente, si necesita caminar a través del bloque asignado dinámicamente, usaría una segunda variable de puntero o usaría un índice de matriz y mantendría la variable de puntero original sin modificar. –

Respuesta

8

Una pérdida de memoria es posible cuando se utiliza malloc() o similares funciones y no llamar free() cuando es necesario. free() siempre debe ser llamado con el puntero devuelto por malloc(), así que sí, si haces algo como esto:

int* ptr = malloc(sizeof(int)); 
free(ptr + 1); 

provoca un comportamiento indefinido. Podría ser una pérdida de memoria, tal vez una falla de segmentación, todo es posible.

+0

Gracias igualdad. Cuando cierre el programa, ¿quedaría la pérdida de memoria? Quiero decir, ¿se ha ido hasta que reinicie la máquina? ¿O depende del sistema operativo que está utilizando? –

+0

@Frank Vilea. La memoria debe ser liberada por su sistema operativo cuando finaliza el proceso. Entonces no necesita reiniciar su máquina. De todos modos, siempre es el sistema operativo el que libera la memoria, por lo que tal vez exista algún SO que no lo haga (no conozco ninguno de ellos). El problema de las pérdidas de memoria es que la aplicación en ejecución consume más memoria de la que necesita. – Heisenbug

+1

Vea esta pregunta para una discusión interesante http://stackoverflow.com/questions/2213627/when-you-exit-ac-application-is-the-malloc-ed-memory-automatically-freed – Joe

4

memoria se produce con la asignación dinámica de memoria. Si almacena un puntero en un segmento de montón que ha asignado y luego modifica esa referencia de puntero, entonces tal vez no podrá liberar la memoria asignada previamente.

Debe utilizar otro puntero y mantener la referencia inicial a la memoria asignada. Por ejemplo:

char *pointer = (char*)malloc (SIZE); /*alloc space for storing a string of size SIZE*/ 
char *pointer2 = pointer; 
int i; 
for (i = 0 ; i < SIZE ; i++){ 
     pointer2 += 1; 
     //you are modifying the second pointer so you always keep a reference to the allocated memory(pointer) 
} 

//now you can call free on your memory 
free(pointer); 
8

La memoria se asigna en el montón. Un puntero es solo eso, un puntero a la ubicación en la memoria. Necesita saber la dirección del inicio de la memoria asignada para liberarla más tarde.

Esto se debe a que el sistema de administración de la memoria debe recordar la información sobre la memoria asignada (por ejemplo, cuánto se asignó) para saber cuánto liberar más adelante y evitar asignar el mismo bloque a otra llamada malloc . La dirección de inicio de la memoria es lo que lo identifica.

Si quiere juguetear con el puntero, tome una copia y no modifique el puntero original.

int *x = malloc(...); 
int *y = x; 

... pointer arithmetic with y 

free(x); 
+0

Gracias Joe, me gusta la idea de evitar tales cosas mediante el uso de una copia. –

1

Puede crear pérdidas de memoria con la aritmética de punteros, haciendo que el punto de puntero en el lugar equivocado, de modo que ya no hay ninguna referencia a la cantidad de memoria que estaba señalando.

Es una pérdida de memoria sin importar si los datos apuntados fueron asignados con malloc() o estáticamente. Las fugas dinámicas de memoria con malloc() son sin embargo peligrosas, mientras que las fugas de memoria estáticas son inofensivas.

Tenga en cuenta que señalar fuera de la matriz es un comportamiento indefinido: cualquier cosa puede suceder. Hacer aritmética de puntero en punteros apuntando a diferentes matrices también es un comportamiento indefinido.

Algunos ejemplos de comportamiento indefinido:

typedef struct 
{ 
    char array1 [6] = "hello"; 
    char array2 [6] = "world"; 
} HelloWorld_t; 


HelloWorld_t hw; 
const char* ptr = hw.array1; 
ptr += 6; /* undefined behavior, out of bounds of the original array */ 
puts(ptr); /* anything can happen here: the program may crash */ 
puts(array2 - 6); /* also undefined behavior */ 
Cuestiones relacionadas