Jump to content

[duvidas] Array Tridimensional


nram
 Share

Recommended Posts

Boas,

Imaginando que tenho um array declarado da seguinte maneira:

char ***nomes;

E outro:

char **concNomes;

Eu através de uma string vou dividi-la para a concNomes, e depois dividir ainda mais, ou seja, o que pretendo é adicionar uma posição ao array ***nomes, concNomes...

imaginando algo do género:


while (s){ //string
//divide para a array **concNomes;
.... 


  //A minha dúvida é aqui, como é que eu aloco no ***nomes, espaço para introduzir concNomes;
  //de modo a ficar nomes[i] = concNomes;
}

Link to comment
Share on other sites

Será algo deste género:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
        char ***nomes;
        **nomes = (char*)malloc(sizeof(char)*(argc));
        nomes[0] = argv;
        return 0;
}

Basicamente, se queres que nomes funcione como um array (como disseste no teu exemplo), então basta que olhes para nomes da seguinte forma:

char* **nomes;

Assim, consegues olhar para o duplo apontador nomes da forma a que estás habituado.

Link to comment
Share on other sites

Será algo deste género:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
        char ***nomes;
        **nomes = (char*)malloc(sizeof(char)*(argc));
        nomes[0] = argv;
        return 0;
}

Basicamente, se queres que nomes funcione como um array (como disseste no teu exemplo), então basta que olhes para nomes da seguinte forma:

char* **nomes;

Assim, consegues olhar para o duplo apontador nomes da forma a que estás habituado.

Acho que é isso...

Só uma coisa, como tenho que alocar, cada vez que entro no ciclo, não tenho que usar o "realloc" ? Se fizer o malloc acho que perco a informação que tenho antes.... certo?

Link to comment
Share on other sites

Acho que é isso...

Só uma coisa, como tenho que alocar, cada vez que entro no ciclo, não tenho que usar o "realloc" ? Se fizer o malloc acho que perco a informação que tenho antes.... certo?

Quando se tem dúvidas, pode-se consultar as páginas do manual através do comando: man realloc, ou então fazer um pequeno exemplo de teste:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
        char *str = (char*)malloc(sizeof(char)*10);
        strncpy(str,"Baderous\0",10);
        printf("%s\n",str);
        str = (char*)realloc(str,sizeof(char)*20);
        strncat(str," portugal\0",20);
        printf("%s\n",str);
        return 0;
}

Que dá como resultado:

Baderous
Baderous portugal

Já agora, mais uma questão.

Como calculo o número de indices de um array (bi, tri,..)... só na coordenada "array[X]"

Ou sabes de antemão o número de índices que alocaste, ou podes ir percorrendo o array nessa coordenada até encontrares um NULL (isto supondo que não existem valores NULL pelo meio, ou seja, que foi tudo inserido sequencialmente no array).

Link to comment
Share on other sites

        char ***nomes;
        **nomes = (char*)malloc(sizeof(char)*(argc));

Visto que **nomes é do tipo char*, isto não devia ficar:

 **nomes = (char*)malloc(sizeof(char*)*(argc));

O tamanho de um char não é o mesmo que o de um char*.

Ou sabes de antemão o número de índices que alocaste, ou podes ir percorrendo o array nessa coordenada até encontrares um NULL (isto supondo que não existem valores NULL pelo meio, ou seja, que foi tudo inserido sequencialmente no array).

Cuidado que o memcpy não assegura que as posição ficam a NULL.

The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.

Para isso é necessário usar o calloc().

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

Eu segui a lógica do "se quando quero alocar espaço para uma string, o parâmetro do sizeof é um char e não um char*, então o mesmo se deve passar neste caso...".

Mas o argv não é uma string (char*), é um char**.

Já estou confuso 🙂

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

Acho que é char**

Quando se faz char * mystring usa-se char porque "mystring" (sem o *) é do tipo char.

Portanto, quando se quer char * ** myarray, devia fazer-se char** porque "**myarray" é do tipo char**.

Ou seja, fica:

        char ***nomes;
        **nomes = (char***)malloc(sizeof(char**)*(argc));

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

É isso, acho que tens razão, vi neste post que é como dizes.

EDIT: e daí não sei, porque no caso desse post, está-se a alocar posição a posição e eu aqui limito-me a alocar uma das dimensões do array, e depois atribuo-lhe um array bidimensional a uma das posições da dimensão alocada!

Link to comment
Share on other sites

Sim, mas o que depois se faz com cada posição (alocar ou apontar) é indiferente, o que interessa é que se está a alocar a primeira dimensão.

int **m = (int**) malloc(sizeof(int*) * 3);

É exactamente o que estamos a fazer, mas com mais uma *, por isso tem que se acrescentar * em todos os sítos.

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

O tamanho de um char não é o mesmo que o de um char*.

Isto é verdadeiro mas p.e. para variáveis do tipo inteiro já não se verifica.

Quando alocámos "a primeira dimensão" dinamicamente de uma matriz tridimensional o que na verdade se está a alocar não são, neste caso, char mas sim char **, visto que primeiro estamos a alocar ponteiros, que vão apontar para ponteiros que vão apontar para char.

Já agora deixo aqui uma imagem que retrata a situação: http://alibad.files.wordpress.com/2010/05/array3d-nonjagged.jpg?w=379&h=500.

Só mesmo para completar, ter char ** ou char * penso que seria indiferente visto que o tamanho é o mesmo e só seria utilizado no operador sizeof.

here since 2009

Link to comment
Share on other sites

Isto é verdadeiro mas p.e. para variáveis do tipo inteiro já não se verifica.

Por acaso isso em 64bits pode acontecer: há compiladores que usam 4 bytes para int's e 8 para pointers.

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

Acho que já tentei de tudo e mais alguma coisa, mas eu não estou a conseguir usar o que me estão a dizer... O meu raciocínio não está nada bom.

char ***ListaComandos, está declarado como triplo apontador, e como disse quero espaço para introduzir novos (duplo apontador) "comandos + argumentos, daí a eu necessitar de um duplo apontador"...

O que acontece, é que eu ao fazer realloc ele faz automáticamente segmentation fault. Mais um pormenor, eu declarar...

Mas segundo o que me consta, é que eu como declarei char ***ListaComandos = NULL, vou ter que fazer um malloc inicialmente para que isto me dê certo...

Alguém que me possa dar uma mãozinha?

**listaComandos = (char*)realloc(listaComandos, sizeof(char*)*(tamanho));
Link to comment
Share on other sites

Não, porque ptr pode ser NULL, e aí o realloc funciona como o malloc.

Estive a fazer uns testes, e o assignment está mal. Terceira tentativa:

char ***listaComandos;
listaComandos = (char***)realloc(listaComandos, sizeof(char**)*(tamanho));

Ou seja, não se usa os '*' antes do nome da variável, se não ele vai guardar a posição de memória que recebe do realloc no local apontado por listaComandos** e não no próprio listaComandos.

❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.