É necessário excluir elementos à medida que uma matriz encolhe?
-
27-09-2019 - |
Pergunta
Sou um aluno escrevendo um método que remove Zeros do final de uma matriz de INTs, em C ++. A matriz está em uma estrutura e a estrutura também possui um INT que acompanha o comprimento da matriz.
O método examina cada elemento a partir do último, até encontrar o primeiro elemento diferente de zero, e marca esse como o "último elemento" alterando o valor do comprimento. Em seguida, o método volta ao "último elemento" original, excluindo os elementos que não estão fora dos limites (os zeros).
A parte que exclui o i
o elemento na matriz se i
é maior que a duração atualizada da matriz, se parece com o seguinte:
if (i > p->length - 1) {
delete (p->elems + i); // free ith elem
Essa linha está errada, no entanto. Delete leva um ponteiro, sim? Então, meu sentimento é que preciso recuperar o ponteiro da matriz e depois adicionar i
Para que eu tenha a localização da memória do número inteiro que quero excluir.
Minha intuição está errada? O erro é sutil? Ou, eu tenho a ideia totalmente errada? Comecei a me perguntar: eu realmente preciso libertar essas primitivas? Se eles não fossem primitivos, eu precisaria e, nesse caso, como eu?
Solução
Se p->elems
é um ponteiro, então também p->elems + i
(Supondo que a operação seja definida, ou seja, I é do tipo integral) - e p->elems + i == &p->elems[i]
De qualquer forma, você provavelmente não deseja (e não pode) excluir o INTS de uma matriz de int (seja dinamicamente ou automaticamente alocado). Aquilo é
int* ptr = new int[10];
delete &ptr[5]; // WRONG!
Isso é simplesmente algo que você não pode fazer. No entanto, se a estrutura contiver o comprimento da matriz, você poderá considerar a matriz "redimensionada" depois de alterar as informações de comprimento contidas pela estrutura - afinal, não há como dizer o tamanho da matriz que um ponteiro aponta.
Se, no entanto, sua matriz é uma variedade de dicas para números inteiros (int*[]
) E esses ponteiros apontam para a memória alocada dinamicamente, então sim, você pode excluir itens únicos e você o fará de acordo com o seu código (você está mostrando tão pouco código que é difícil ser exato).
Outras dicas
Eu tenho a ideia totalmente errada?
Temo que sim.
Se você fizer um new[]
Ligue para alocar uma matriz, então você deve fazer um delete[]
Ligue para libertá -lo:
int *p = new int[10];
...
delete[] p;
Se sua matriz estiver em uma estrutura e você fizer uma chamada para alocar a estrutura, você deve fazer uma chamada para libertá -la:
struct Foo {
int data[10];
};
Foo *foo = new Foo;
...
delete foo;
Não há como libertar parte de uma matriz.
Um int[10]
Array na verdade é 10 números inteiros, seguidos (ou seja, 40 bytes de memória em um sistema de 32 bits, talvez mais sobrecarga). O número inteiro valores que são armazenados na matriz Occupy essa memória - eles não são alocações de memória e não precisam ser libertadas.
Tudo isso dito, se você quiser uma matriz de comprimento variável:
É para isso que serve a std :: vetor
#include <vector>
#include <iostream>
struct Foo {
std::vector<int> vec;
};
int main() {
Foo foo;
// no need for a separate length: the current length of the vector is
std::cout << foo.vec.size() << "\n";
// change the size of the vector to 10 (fills with 0)
foo.vec.resize(10);
// change the size of the vector to 7, discarding the last 3 elements
foo.vec.resize(7);
}