Problema con asignación dinamica de memoria.

Iniciado por ThePinkPanther, 2 Febrero 2013, 23:44 PM

0 Miembros y 1 Visitante están viendo este tema.

ThePinkPanther

//includes
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
//globales
struct alumno
{
string nombre;
string apellido;
};
struct alumno info;
//prototipo de funciones

//funcion main



int main()
{
float aux=0;
int contador=0;
float *notas=NULL;


cout<<"Nombre del alumno : "  ; cin>>info.nombre;
cout<<endl<<"Apellido del alumno : " ; cin>>info.apellido;
cout<<endl;
cout<<"Ingrese las notas y presione entrar,para terminar el ingreso de datos use 0.."<<endl;
do
{
cout<<"nota numero " << contador+1 << " : " ;cin>>aux;
notas=(float*)realloc(notas,sizeof(float)*contador);
notas[contador]=aux;
contador++;
}
while(aux!=0);


free(notas);
}


estaba haciendo programa , el siguiente :

CitarEscriba un programa que lea los datos de un alumno:nombre, apellido, y una lista de calificaciones correspondiente a todos sus exámenes finales (se desconoce a priori el número de exámenes rendidos). El programa debe calcular el promedio del alumno en la carrera en informarlo en pantalla.

al introducir mas de 5 notas, me tira error de ...

*** glibc detected *** /home/mmokk/Escritorio/dinamico: realloc(): invalid next size: 0x08fc30a8 ***

lei que cuando el puntero es NULL , la funcion realloc funciona como malloc, después cuando el puntero tiene asignada una direccion de memoria que apunta a la memoria , después de 5 notas sale el error descrito arriba.

Compilo bajo ubuntu linux con g++ ..

Alguien puede ayudarme ?.

Gracias de antemano  :P

naderST

#1
Estás reservando un elemento menos en cada iteración:

notas=(float*)realloc(notas,sizeof(float)*contador);

En la primera iteración contador es cero estás reservando cero bytes... deberías hacer "contador + 1" ya que necesitas reservar espacio para contador+1 elementos.

EDIT:

No había leído el enunciado del problema, no hace falta utilizar memoria dinámica, simplemente puedes ir sumando las notas y llevar un contador de las notas que ha ido introduciendo y luego sacas la media con eso.

ThePinkPanther

Cita de: naderST en  3 Febrero 2013, 01:21 AM
Estás reservando un elemento menos en cada iteración:

notas=(float*)realloc(notas,sizeof(float)*contador);

En la primera iteración contador es cero estás reservando cero bytes... deberías hacer "contador + 1" ya que necesitas reservar espacio para contador+1 elementos.
Perfecto gracias , pero aunque a contador lo inicialize en 1 como acabo de hacer, en vez de a los 5 , a las 4 notas surge el siguiente error..

*** glibc detected *** /home/mmokk/Escritorio/Programacion/dinamico: realloc(): invalid next size: 0x08b820a8 ***

naderST

Cita de: Puredepapas en  3 Febrero 2013, 01:35 AM
Perfecto gracias , pero aunque a contador lo inicialize en 1 como acabo de hacer, en vez de a los 5 , a las 4 notas surge el siguiente error..

*** glibc detected *** /home/mmokk/Escritorio/Programacion/dinamico: realloc(): invalid next size: 0x08b820a8 ***


Si lo inicias en uno debes asegurarte de cuando accedas a un elemento del arreglo lo hagas de la siguiente manera:

notas[contador-1]=aux;

ya que el arreglo va de 0 a n-1

ThePinkPanther

Mi problema se soluciono . muchisimas gracias (:

amchacon

Una cosa, en C++ tienes el operador new/delete para reservar dinámicamente la memoria, no necesitas el alloc:

Código (cpp) [Seleccionar]
notas = new float[contador];
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

ThePinkPanther

Cita de: amchacon en  3 Febrero 2013, 03:46 AM
Una cosa, en C++ tienes el operador new/delete para reservar dinámicamente la memoria, no necesitas el alloc:

Código (cpp) [Seleccionar]
notas = new float[contador];

Gracias .. se que se escapa del tema pero... si uso

notas=new float[contador];
notas=new float[contador*2];


el segundo new funcionaria como realloc ? como haria la reasignación de memoria cuando ya invoque a new antes ?

saludos

amchacon

Cita de: Puredepapas en  3 Febrero 2013, 04:19 AM
Gracias .. se que se escapa del tema pero... si uso

notas=new float[contador];
notas=new float[contador*2];


el segundo new funcionaria como realloc ? como haria la reasignación de memoria cuando ya invoque a new antes ?

saludos
Cada llamada a new, reserva una porción de memoria y te devuelve el puntero con la dirreción.

Si pones dos llamadas seguidas, harán lo mismo, pero al hacer la segunda perderías la dirreción de la anterior y tendrías una fuga de memoria:
http://www.youtube.com/watch?v=Y9eYr8zGGIg

Tienes que borrar la memoria cogida antes de hacer un nuevo new:
notas=new float[contador];
delete[] notas;
notas=new float[contador*2];


Para más información:
http://c.conclase.net/curso/index.php?cap=013b
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

rir3760

Cita de: Puredepapas en  3 Febrero 2013, 04:19 AMse que se escapa del tema pero... si uso

notas=new float[contador];
notas=new float[contador*2];


el segundo new funcionaria como realloc?
No.

Cita de: Puredepapas en  3 Febrero 2013, 04:19 AMcomo haria la reasignación de memoria cuando ya invoque a new antes ?
En C++ evitas la reasignación, en su lugar utilizas un contenedor, por ejemplo la clase vector.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

ThePinkPanther

#9
Citar
No había leído el enunciado del problema, no hace falta utilizar memoria dinámica, simplemente puedes ir sumando las notas y llevar un contador de las notas que ha ido introduciendo y luego sacas la media con eso.

es verdad.solo lo hice de practica..

Gracias por sus ayudas.. me sirvieron . UN SALUDO !