Olá, o tópico ficou meio longo, mas é que o problema é meio complicado mesmo...
Estou desenvolvendo um programa que faz diversas operações com algumas matrizes. Como o tamanho das matrizes é desconhecido usei apenas ponteiros e alocação dinâmica. O problema é que o código começou a dar problema a partir de 1 alocação específica (sempre a mesma) em um local do código completamente inesperado. Pesquisei em todo lugar e não tenho a mínima idéia do que poderia ser, então se pudessem me ajudar agradeceria muito.
(a notação é de c++)
Explicação básico do código:
-No futuro ele irá pegar dados de um arquivo, mas por enquanto simplesmente inicializei internamente em getdatafiles().
-O programa só está com as partes de processamento, que ocorrem dentro de treat_data(). Depois que essa função funcionar direito existirão outras de entrada e saída de dados. Talvez eu puxe as funções de processamento para dentro da classe e faça o objeto calcular seus próprios dados.
-Primeiro a array é normalizada em 1 sentido e depois é tirada a média no outro sentido. Para que as funções average() e normalize() sejam mais poderosas e possam ser reutilizadas coloquei um argumento que indica a dimensão "fixa", assim dá pra fazer na vertical ou horizontal.
-Como o problema ocorre dentro de average() as funções pra baixo (dentro de treat_data()) não são nem executadas, então o problema não pode estar nelas.
-Como estavam aparecendo esses erros de execução criei uma funçaõ temporária parray() para imprimi uma array 2D.
#################### O ERRO ENTÃO: ################
Na execução average() é executada 3 vezes. Na primeira e segunda tudo ocorre perfeitamente (com valores testados com parray() ). O problema é na 3 vez: ele dá erro de execução dentro de parray(), pois o operador new retornou um valor != null, mas com endereço que não pode ser acessado. Então coloquei
cout<<"&="<<avg2<<" value="<<*avg2<<endl;
logo depois de avg2 ser criado, e ele digita o texto até o final, mas quando vai digitar o "valor" e acessar o ponteiro o programa trava e não encerra nem com ctrl^c, preciso ir no gerenciador de tarefas (estou com Windows), o mesmo problema que ocorre dentro de parray().
O mais estranho é que o programa já rodou corretamente até o final algumas vezes, mas geralmente trava (sempre no mesmo lugar). Quando rodo em modo Debug(F8) a execução ocorre sempre perfeita. Vai entender...
Recompilei n vezes em 3 computadores tanto com gcc++ e Borland c++5.5, revi o código inteiro, reiniciei o computador, testei valor por valor, pesquisei em tudo que é forum ou site de programação e nada. Meu próximo passo seria tentar abandonar a notaçaõ C++ e usar malloc, mas pra não ter que mudar o código inteiro vou tentar achar uma solução antes. De qualquer modo já utilizei malloc apenas no local do problema e não resolveu, só não tentei subsituir tudo ainda.
Quando o programa roda até o fim (usando debug, por exemplo) vejo que todos os valores calculados estão corretos, ou seja: não existe erro de lógica muito aparente e todas as matrizes são corretamente criadas e acessadas.
O que poderia ser isso???? Agradeço toda ajuda.
###########DETALHES ADICIONAIS##############
Só agora percebi uma coisa: o programa trava se eu indico "*avg2", mas dentro de average existe a linha "avg2[x]=sum/n;" que aparentemente não deu problema nenhum...
Ultima informação: quando ponho pra executar ele aparece usando cerca de 2MB de memória, mas o programa só tem ~450KB e as variáveis não passam de 0,5KB. Esses 2MB não são uma "margem" criada automaticamente pelo Windows, pois o valor flutua ~300KB pra cima e pra baixo, algo que não aconteceria com essa folga toda. Depois que mando parar o processo a memória não é desalocada (cada execução inutiliza 2MB de memória).
Será que isso é virus? Como poderia infectar logo que o programa é compilado?
Alguém poderia me dar uma luz, nem que seja só um palpite, sobre esse erro? Preciso desse código funcionando (na verdade esse é só o começo dele, o resto nem começei a fazer) para meu trabalho de iniciação científica, e se eu nem descobrir porque ocorre fica difícil.
#include <iostream>
using std::cout;
using std::cin;
using std::ios;
using std::cerr;
using std::endl;
#include <fstream>
using std::ofstream;
using std::ifstream;
#include <cstdlib>
#include <cstdio>
#define LIMCRIT 3
#define LIMALT 3
//Classes utilizadas
class Data{
public:
int numcrit, numalt; //numero de critérios e alternativas.
int esccrit, escalt; //escala utilizada (de 1 a n).
double intercrit[LIMCRIT][LIMCRIT]; //array com relaçaõ entre critérios.
double interalt[LIMCRIT][LIMALT][LIMALT];
//arrays com rel entre alternativas, segundo critério.
};
class Average{
public:
//ponteiros porque as funções pegam array de dados, criam uma array dinâmica e
//devolvem o endereço.
double *imp_C; //array de importância abs de cada critério.
double *imp_relA[]; //arrays de importância relativa de cada alt
//segundo critério.
};
class Results{
public:
double *indexA; //indice de cada alternativa.
int *idalt; //num da alternativa (indexA está ordenada)
//logo, posição inicial foi alterada.
};
class Interviewee{
public:
Data *data;
Average *avgs;
Results * ress;
};
//protótipos de funções
Data * getdatafiles();
Interviewee *treat_data(Data *);
bool normalize(double *, int m, int n, int d); //normaliza array de 2 de dimensões
//sendo calculada sobre a dimensão 'd'. 'm''n'==M[m][n]
double * average(double *, int m, int n, int d); //== a normalize(), mas calcula média
Interviewee * assize(Interviewee *); //baseada nas médias calcula o index de cada alternativa
//e ordena do maior para o menor.
bool order(Results *res, int end); //ordena do maior para o menor (método bolha)
void gather(double *[],int,int); //junta na memória arrays dispersas 1D em 1 array 2D
void parray(double*, int, int, char*);
int main(){
Interviewee *res;
Data *dat;
char r;
//Pega dados dos arquivos e aloca internamente
dat=getdatafiles();
//Processa completamente os dados e dá resultado final
res=treat_data(dat);
if(res==0){
cout<<"Erro interno inesperado. Dados não puderam ser processados."<<endl;
cout<<"O programa será encerrado."<<endl;
system("pause");
return 0;
}
system("pause");
return 0;
}
Data * getdatafiles(){
static Data *d;
d=new Data;
d->numalt=3;
d->numcrit=3;
d->esccrit=3;
d->escalt=3;
d->intercrit[0][0]=1;
d->intercrit[0][1]=2;
d->intercrit[0][2]=2;
d->intercrit[1][0]=0,5;
d->intercrit[1][1]=1;
d->intercrit[1][2]=2;
d->intercrit[2][0]=0,5;
d->intercrit[2][1]=0,5;
d->intercrit[2][2]=1;
for(int crit=0; crit<d->numcrit; crit++){
d->interalt[crit][0][0]=1;
d->interalt[crit][0][1]=2;
d->interalt[crit][0][2]=2;
d->interalt[crit][1][0]=0,5;
d->interalt[crit][1][1]=1;
d->interalt[crit][1][2]=2;
d->interalt[crit][2][0]=0,5;
d->interalt[crit][2][1]=0,5;
d->interalt[crit][2][2]=1;
}
return d;
}
Interviewee *treat_data(Data * dat){
static Interviewee* p;
p=new Interviewee;
if(p==0)
return 0;
p->ress=new Results;
p->avgs=new Average;
p->data=dat;
normalize(p->data->intercrit[0],p->data->numcrit,p->data->numcrit,1);
parray(p->data->intercrit[0],p->data->numcrit,p->data->numcrit,"intercrit");
for(int crit=0;crit<p->data->numcrit;crit++){
normalize(&(p->data->interalt[crit][0][0]),p->data->numalt,p->data->numalt,1);
parray(&(p->data->interalt[crit][0][0]),p->data->numalt,p->data->numalt,"interalt");
}
p->avgs->imp_C = average(p->data->intercrit[0], p->data->numcrit, p->data->numcrit, 2);
parray(p->data->intercrit[0],p->data->numcrit,p->data->numcrit,"intercrit");
parray(p->avgs->imp_C,1,p->data->numcrit,"imp_C");
for(int crit=0;crit<p->data->numcrit;crit++){
p->avgs->imp_relA[crit] = average(&(p->data->interalt[crit][0][0]), p->data->numalt, p->data->numalt, 2);
cout<<"crit="<<crit<<endl<<endl<<endl;
}
gather(p->avgs->imp_relA, p->data->numcrit, p->data->numalt);
parray(p->avgs->imp_relA[0],p->data->numcrit,p->data->numalt,"imp_relA");
p=assize(p);
parray(p->ress->indexA,1,p->data->numalt,"indexA");
return p;
}
bool normalize(double *ar, int m, int n, int d){
double sum=0;
if(d!=1 && d!=2)
return false;
for(int x=0; x<m; x++){
for(int y=0; y<n; y++){
if(d==1)
sum+=*(ar+x+y*n);
else sum+=*(ar+x*n+y);
}
for(int y=0; y<n; y++){
if(d==1)
*(ar+x+y*n)/=sum;
else *(ar+x*n+y)/=sum;
}
sum=0;
}
return true;
}
double * average(double *ar, const int m, const int n, int d){
static double *avg1, *avg2;
double sum=0;
if(d!=1 && d!=2)
return 0;
if(d==1){
avg1=new double[n];
for(int x=0; x<m; x++){
for(int y=0; y<n; y++)
sum+=*(ar+x+y*n);
avg1[x]=sum/m;
sum=0;
}
parray(avg1,1,n,"avg1");
return avg1;
}else{
avg2=new double[m];
for(int x=0; x<m; x++){
for(int y=0; y<n; y++)
sum+=*(ar+x*n+y);
avg2[x]=sum/n;
sum=0;
}
parray(avg2,1,m,"avg2");
return avg2;
}
}
Interviewee * assize(Interviewee * p){
int crit, alt;
p->ress->indexA=new double[p->data->numalt];
p->ress->idalt=new int[p->data->numalt];
for(alt=0; alt < p->data->numalt; alt++){
p->ress->indexA[alt]=0;
p->ress->idalt[alt]=alt;
for(crit=0; crit < p->data->numcrit; crit++){
p->ress->indexA[alt]+= p->avgs->imp_relA[crit][alt] * p->avgs->imp_C[crit];
}
}
if(order(p->ress,p->data->numalt)==false){
cout<<"Erro para ordenar, verifique o código."<<endl;
return 0;
}
return p;
}
bool order(Results *res, int end){
bool c=true;
double aux=0;
int alt, aux2;
while(c==true){
c=false;
for(alt=0; alt+1<end; alt++){
if(res->indexA[alt] < res->indexA[alt+1]){
c=true;
aux=res->indexA[alt+1];
res->indexA[alt+1] = res->indexA[alt];
res->indexA[alt] = aux;
aux2=res->idalt[alt+1];
res->idalt[alt+1] = res->idalt[alt];
res->idalt[alt] = aux2;
}
}
end--;
}
return true;
}
void parray(double* a,int m,int n, char* title){ //matriz unidimensional == parray(*,1,n,*);
cout<<title<<endl;
for(int x=0;x<m;x++){
for(int y=0; y<n; y++)
cout<<*(a+x*n+y)<<" ";
cout<<endl;
}
cout<<endl<<endl<<endl<<endl;
}
void gather(double *a[],const int q,const int t){
double *aux;
aux=new double[q*t];
for(int x=0; x<q; x++)
for(int y=0; y<t; y++)
*(aux+x*t+y)=*(a[x]+y);
for(int x=0;x<q; x++){
delete[] a[x];
a[x]=aux+x*t;
}
}
Pergunta
barutaji
Olá, o tópico ficou meio longo, mas é que o problema é meio complicado mesmo...
Estou desenvolvendo um programa que faz diversas operações com algumas matrizes. Como o tamanho das matrizes é desconhecido usei apenas ponteiros e alocação dinâmica. O problema é que o código começou a dar problema a partir de 1 alocação específica (sempre a mesma) em um local do código completamente inesperado. Pesquisei em todo lugar e não tenho a mínima idéia do que poderia ser, então se pudessem me ajudar agradeceria muito.
(a notação é de c++)
Explicação básico do código:
-No futuro ele irá pegar dados de um arquivo, mas por enquanto simplesmente inicializei internamente em getdatafiles().
-O programa só está com as partes de processamento, que ocorrem dentro de treat_data(). Depois que essa função funcionar direito existirão outras de entrada e saída de dados. Talvez eu puxe as funções de processamento para dentro da classe e faça o objeto calcular seus próprios dados.
-Primeiro a array é normalizada em 1 sentido e depois é tirada a média no outro sentido. Para que as funções average() e normalize() sejam mais poderosas e possam ser reutilizadas coloquei um argumento que indica a dimensão "fixa", assim dá pra fazer na vertical ou horizontal.
-Como o problema ocorre dentro de average() as funções pra baixo (dentro de treat_data()) não são nem executadas, então o problema não pode estar nelas.
-Como estavam aparecendo esses erros de execução criei uma funçaõ temporária parray() para imprimi uma array 2D.
#################### O ERRO ENTÃO: ################
Na execução average() é executada 3 vezes. Na primeira e segunda tudo ocorre perfeitamente (com valores testados com parray() ). O problema é na 3 vez: ele dá erro de execução dentro de parray(), pois o operador new retornou um valor != null, mas com endereço que não pode ser acessado. Então coloquei
cout<<"&="<<avg2<<" value="<<*avg2<<endl;
logo depois de avg2 ser criado, e ele digita o texto até o final, mas quando vai digitar o "valor" e acessar o ponteiro o programa trava e não encerra nem com ctrl^c, preciso ir no gerenciador de tarefas (estou com Windows), o mesmo problema que ocorre dentro de parray().
O mais estranho é que o programa já rodou corretamente até o final algumas vezes, mas geralmente trava (sempre no mesmo lugar). Quando rodo em modo Debug(F8) a execução ocorre sempre perfeita. Vai entender...
Recompilei n vezes em 3 computadores tanto com gcc++ e Borland c++5.5, revi o código inteiro, reiniciei o computador, testei valor por valor, pesquisei em tudo que é forum ou site de programação e nada. Meu próximo passo seria tentar abandonar a notaçaõ C++ e usar malloc, mas pra não ter que mudar o código inteiro vou tentar achar uma solução antes. De qualquer modo já utilizei malloc apenas no local do problema e não resolveu, só não tentei subsituir tudo ainda.
Quando o programa roda até o fim (usando debug, por exemplo) vejo que todos os valores calculados estão corretos, ou seja: não existe erro de lógica muito aparente e todas as matrizes são corretamente criadas e acessadas.
O que poderia ser isso???? Agradeço toda ajuda.
###########DETALHES ADICIONAIS##############
Só agora percebi uma coisa: o programa trava se eu indico "*avg2", mas dentro de average existe a linha "avg2[x]=sum/n;" que aparentemente não deu problema nenhum...
Ultima informação: quando ponho pra executar ele aparece usando cerca de 2MB de memória, mas o programa só tem ~450KB e as variáveis não passam de 0,5KB. Esses 2MB não são uma "margem" criada automaticamente pelo Windows, pois o valor flutua ~300KB pra cima e pra baixo, algo que não aconteceria com essa folga toda. Depois que mando parar o processo a memória não é desalocada (cada execução inutiliza 2MB de memória).
Será que isso é virus? Como poderia infectar logo que o programa é compilado?
Alguém poderia me dar uma luz, nem que seja só um palpite, sobre esse erro? Preciso desse código funcionando (na verdade esse é só o começo dele, o resto nem começei a fazer) para meu trabalho de iniciação científica, e se eu nem descobrir porque ocorre fica difícil.
Link para o comentário
Compartilhar em outros sites
1 resposta a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.