una - matriz en c++ codigo
¿Qué pasa si elimino una matriz una vez en C++, pero la asigno varias veces? (6)
Supongamos que tengo el siguiente fragmento.
int main()
{
int num;
int* cost;
while(cin >> num)
{
int sum = 0;
if (num == 0)
break;
// Dynamically allocate the array and set to all zeros
cost = new int [num];
memset(cost, 0, num);
for (int i = 0; i < num; i++)
{
cin >> cost[i];
sum += cost[i];
}
cout << sum/num;
}
` `delete[] cost;
return 0;
}
Aunque puedo mover la instrucción delete
dentro del ciclo while para mi código, para fines de comprensión, quiero saber qué ocurre con el código tal como está escrito. ¿Asigna C ++ diferentes espacios de memoria cada vez que uso un operador new
?
¿El operador delete
solo elimina la última matriz de cost
asignados?
¿Asigna C ++ diferentes espacios de memoria cada vez que uso un operador
new
?
Sí.
¿El operador
delete
solo elimina la última matriz decost
asignados?
Sí.
Perdiste los únicos consejos para los demás, por lo que se filtran irrevocablemente. Para evitar este problema, no haga malabares con los punteros, pero use RAII para administrar los recursos dinámicos automáticamente. std::vector
sería perfecto aquí (si realmente necesitaras una matriz, tu ejemplo podría seguir leyendo y reutilizando una única int
).
Cada vez que asigna nueva memoria para la matriz, se filtra la memoria que se ha asignado previamente. Como regla general, debe liberar memoria tantas veces como haya asignado.
Le recomiendo encarecidamente que no use "C idioms" en un programa C ++ . Deje que la biblioteca std
trabaje para usted: es por eso que está ahí. Si desea "una matriz (vector) de n enteros", entonces de eso se trata std::vector
, y "viene con baterías incluidas". No tiene que preocuparse por cosas como "establecer un tamaño máximo" o "configurarlo en cero". Usted simplemente trabaja con "esto" , cuyo funcionamiento interno no tiene que preocuparse, sabiendo que ya ha sido diseñado y probado completamente.
Además, cuando haces esto, estás trabajando dentro del marco existente de C ++ para la gestión de memoria. En particular, no está haciendo nada "fuera de banda" dentro de su propia aplicación "que la biblioteca estándar no conoce, y que podría (¡) subir".
C ++ le brinda una biblioteca muy completa de funcionalidades rápidas, eficientes, robustas y bien probadas. Aprovecharlo .
No hay cost
matriz de cost
en su código. En su código, el cost
es un puntero , no una matriz.
Las matrices reales en su código se crean mediante new int [num]
llamadas new int [num]
repetitivas. Cada llamada a new crea un nuevo objeto de matriz sin nombre que vive en algún lugar de la memoria dinámica. La nueva matriz, una vez creada por la new[]
, es accesible a través del puntero de cost
. Dado que la matriz no tiene nombre , ese puntero de cost
es el único enlace que tiene que conduce a la matriz sin nombre creada por la new[]
. No tienes otro medio para acceder a esa matriz sin nombre.
Y cada vez que hace ese cost = new int [num]
en su ciclo, está creando un conjunto completamente nuevo y diferente, rompiendo el enlace del cost
al conjunto anterior y haciendo que el cost
apunte al nuevo.
Como el cost
era su único vínculo con la matriz anterior, esa matriz anterior se vuelve inaccesible. El acceso a esa matriz anterior se pierde para siempre. Se convierte en una pérdida de memoria.
Como usted mismo declaró correctamente, su expresión delete[]
solo desasigna la última matriz, el único cost
termina apuntando al final. Por supuesto, esto solo es cierto si su código alguna vez ejecuta la línea cost = new int [num]
. Tenga en cuenta que su ciclo puede finalizar sin realizar una sola asignación, en cuyo caso aplicará delete[]
a un puntero no inicializado (basura).
Primero fuera de esta línea está mal:
memset(cost, 0, num);
Supone que int es solo un char de largo. Más típicamente son cuatro. Debería usar algo como esto si quiere usar memset para inicializar la matriz:
memset(cost, 0, num*sizeof(*cost));
O mejor aún, descargue el memset y utilícelo cuando asigne la memoria:
cost = new int[num]();
Como otros han señalado, la eliminación está mal colocada y perderá toda la memoria asignada por su correspondiente nueva, excepto la última. Moverlo al lazo.
Sí. Así que obtienes una pérdida de memoria para cada iteración del ciclo excepto la última.
Cuando usa new
, asigna un nuevo fragmento de memoria. Asignar el resultado de lo new
a un puntero solo cambia lo que señala este puntero. No libera automáticamente la memoria a la que hacía referencia este puntero (si la había).