Matrizes

1. Matrizes

André Felipe Jesus do Nascimento Silva
andredrummer

(usa Outra)

Enviado em 24/11/2018 - 20:35h

Galera, estou tentando codar um algoritmo que calcula o numero minimo de operações escalares de uma cadeia de matrizes, porem no codigo que eu fiz, logo apos definir a quanidade de matrizes e preencher o vetor de dimensoes das matrizes o codigo falha e fecha o programa. Alguem ai poderia rodar esse codigo e me ajudar a reslver esse problema. Ja tenho um tempao quebrando cabeça...

#include<bits/stdc++.h>
using namespace std;

int **cust_Minimum(std::vector<int> vet);
void print_Parents();


int main()
{
setlocale(LC_ALL, "");

unsigned int n, l, c;
cout<<"Quantas matrizes? ";
cin>>n;

std::vector<int> vetorDimensoes;
int **S;

cout<<"Digite a ordem da matriz separada por espaço. Ex.: 2x2 = 2 2\n\n";
for(int m = 0; m < n; m++)
{
cout<<"Matriz "<<m+1<<": ";
cin>>l>>c;
vetorDimensoes.push_back(l);
if(m==n-1)
{
vetorDimensoes.push_back(c);
}
}

int **M = cust_Minimum(vetorDimensoes);

return 0;

}

int **cust_Minimum(std::vector<int> vet)
{
int n = vet.size()-1;
int **M = (int**)malloc(n*sizeof(int)), **S = (int**)malloc(n*sizeof(int));
for(int i = 1; i<=n; i++)
{
M[i][i]=0;
}
for(int l = 2; l <= n; l++)
{
for(int i = 1; i < n-l+1;i++)
{
int j = i+l-1;
for(int k = i; k < j-1; k++)
{
int q = M[i][k] + M[k+1][j] + vet[i-1] * vet[k] * vet[j];
if (q < M[i][j])
{
M[i][j]=q;
S[i][j]=k;
}
}
}
}
return M;
}



  


2. Re: Matrizes

Fernando
phoemur

(usa Debian)

Enviado em 25/11/2018 - 09:50h

Primeiramente você precisa se decidir se vai usar C ou C++, pois são SIM coisas completamente diferentes.
Esse monte se ponteiros e mallloc em C++ não é considerado boa prática de programação.
Apesar de ser compatível, não faz sentido fazer as coisas em C++ da mesma forma que se faz em C.
Se for pra fazer assim use C logo. Não misture as coisas.

Quanto ao seu erro é uma coisa básica e comum:

você aloca duas matrizes de tamanho n com
int **M  = (int**)malloc(n*sizeof(int)), **S  = (int**)malloc(n*sizeof(int)); 

porém assim está errado.
O certo seria algo assim
int **mat = (int **)malloc(rows * sizeof(int*));
for(int i = 0; i < rows; i++) mat[i] = (int *)malloc(cols * sizeof(int));

Você está acessando memória que não foi alocada e por isso a falha de segmentação.

E também acessa até o elemento n+1 (fez isso mais de uma vez), o que também daria SIGSEGV

for(int i = 1; i<=n; i++)
{
M[i][i]=0;
}


Você também não usou free na memória que alocou, vazando memória.
Tem mais coisas também, mas o que eu falei é o mais grave.

Percebe os problemas que inadvertidamente colocamos nos nossos programas?
Não seria mais fácil usar apenas std::vector e não se preocupar com essas coisas ?

Abração
______________________
https://github.com/phoemur


3. Re: Matrizes

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/11/2018 - 12:39h

phoemur escreveu:

Primeiramente você precisa se decidir se vai usar C ou C++, pois são SIM coisas completamente diferentes.
Esse monte se ponteiros e mallloc em C++ não é considerado boa prática de programação.
Apesar de ser compatível, não faz sentido fazer as coisas em C++ da mesma forma que se faz em C.
Se for pra fazer assim use C logo. Não misture as coisas.

( ... )

O certo seria algo assim
int **mat = (int **)malloc(rows * sizeof(int*));
for(int i = 0; i < rows; i++) mat[i] = (int *)malloc(cols * sizeof(int));


Na verdade, já que é C++, o melhor mesmo seria usar (std::vector, mas restringindo-nos a ponteiros diretamente) o seguinte:
int **m=new int *[rows];
for(size_t i=0; i<rows; i++) m[i]=new int[cols];


E depois ter-se-ia de limpar essas alocações.
for(size_t i=rows; i--;) delete[] m[i];
delete[] m;


Com std::vector tudo é muito melhor, obviamente: a declaração providencia todas as alocações necessárias, e não é preciso preocupar com desalocações.
// ‘m’ é um vetor de vetores, inicializado com ‘rows’ elementos que são, por sua vez, inicializados
// com vetores de inteiros com ‘cols’ elementos, cujos valores são iguais ao maior inteiro representável.
vector<vector<int>> m(rows, vector<int>(cols, numeric_limits<int>::max()));


Você está acessando memória que não foi alocada e por isso a falha de segmentação.

E também acessa até o elemento n+1 (fez isso mais de uma vez), o que também daria SIGSEGV
for(int i = 1; i<=n; i++) 


Deveria ser “<n”.

E contra esse tipo de descuido, usar std::vector não protegeria diretamente — a não ser que se trocasse a forma “m[i][j]” por “m.at(i).at(j)” (e, mesmo assim, ainda seria um erro, mas que dispararia uma exceção controlada, em vez de sair corrompendo memória até o programa dar pau).


4. Re: Matrizes

Fernando
phoemur

(usa Debian)

Enviado em 25/11/2018 - 14:02h

E contra esse tipo de descuido, usar std::vector não protegeria diretamente — a não ser que se trocasse a forma “m[i][j]” por “m.at(i).at(j)” (e, mesmo assim, ainda seria um erro, mas que dispararia uma exceção controlada, em vez de sair corrompendo memória até o programa dar pau).


Outra opção seria utilizar iterators (std::vector::begin, std::vector::end). Daí isso não aconteceria.
C++ moderno, se utilizado corretamente, evita a maioria desses bugs por descuido do programador. O problema é que o pessoal costuma utilizar C++ como se estivesse programando em C no estilo K&R (nada contra aliás, mas cada coisa em seu lugar).

Mas estamos falando a mesma coisa, estou até sendo redundante.
Forte abraço.

______________________
https://github.com/phoemur


5. Re: Matrizes

André Felipe Jesus do Nascimento Silva
andredrummer

(usa Outra)

Enviado em 26/11/2018 - 17:13h

Perfeito!!! Eu estava mesmo alocandi memoria de forma errada e tentando acessar um espaco que não havia alocado. Quanto a definição de que linguagem usar, isso é importante sim. Vou aderir. Mas valeu galera... programa funfa bunitinho agr...






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts