Impossible de convertir double en double **

J’ai une fonction qui prend 3 parameters, le premier est ** double.

normalizeDataZeroMeanUnitSD(double ** trainingActions, int numberOfTrainingActions, int descriptorDimension) 

Lorsque je l’appelle depuis main, j’essaie d’utiliser normalizeDataZeroMeanUnitSD (data, 681, 24); cependant, je reçois

 cannot convert parameter 1 from 'double [681][24]' to 'double **' 

Voici comment je construis le tableau de données:

 fstream infile; infile.open("gabor\\Data.txt"); double data[681][24]; while (!infile.eof()) { for(int j=0;j<681;j++) { for(int k=0; k> data[j][k]; } } } infile.close(); 

Existe-t-il un moyen de faire la même chose avec ** données?

Utilisez l’une des déclarations suivantes. Les deux sont équivalents.

 NormalizeDataZeroMeanUnitSD(double trainingActions[][24], int numberOfTrainingActions, int descriptorDimension) NormalizeDataZeroMeanUnitSD(double trainingActions[681][24], int numberOfTrainingActions, int descriptorDimension) 

Lorsque vous déclarez un tableau 2D, il occupe des emplacements mémoire contigus. Vous devez donc spécifier au moins le nombre de colonnes (en cas d’architecture majeure en ligne).

Jetez un coup d’œil à cela pour les définitions de majeur de ligne et de colonne.

Pour votre question modifiée, oui, vous pouvez déclarer en utilisant **data . Allouer dynamicment le tableau de data . Mais souvenez-vous de le libérer quand vous en aurez fini.

 double **data=new double*[681]; for (int i=0;i<681;i++) { data[i]=new double[24]; } //do what you want to do for (int i=0;i<681;i++) { delete [] data[i]; } delete [] data; 

Votre prototype de fonction peut maintenant ressembler à void func(double **pp) car les data sont un pointeur et non un tableau 2D.

L’erreur est assez claire: le type de données double [681][24] n’est pas la même chose que double ** . S’il est vrai que double[681] peut se décomposer en un pointeur vers son premier élément (donc double* ), cela n’implique pas que double[681][24] peut se décomposer en double** .

Pensez-y de cette façon: double** implique un pointeur vers de nombreux pointeurs. Mais double[][] ne contient AUCUN indicateur. Au mieux, un tableau de TOUTES dimensions n’a encore qu’un seul pointeur: au début de son stockage contigu.

Vous pouvez utiliser un modèle:

 template void normalizeDataZeroMeanUnitSD(double (&trainingActions)[M][N], int descriptorDimension) { for( std::size_t m = 0; m < M; ++m ) { for( std::size_t n = 0; n < N; ++n ) { trainingActions[m][n] = ...; } } } 

Mais méfiez-vous du code gonflé si vous appelez cela avec de nombreux tableaux de tailles différentes.

Un tableau 2D est une zone de stockage continue. La fonction attend un pointeur sur les pointeurs. Ce sont incompatibles.

La fonction attend un tableau de pointeurs sur les tableaux. vous avez un tableau de tableaux. Certaines options sont:

  • changez la fonction pour prendre un type plus convivial, peut-être un double* pointant sur le premier élément d’un tableau bidimensionnel contigu; ou
  • construire un tableau séparé de pointeurs pointant vers chaque ligne de votre tableau à 2 dimensions; ou
  • restructurez vos données dans un tableau de pointeurs vers des tableaux.

Voici une réponse constructive pour savoir comment le faire fonctionner.

Fondamentalement, vous devez générer un tableau contenant des pointeurs sur chaque tranche 1D de votre tableau 2D.

 double data[N][M] = {...}; double *dataPtrs[N]; for(size_t n=0; n 

Yay, je dois encore parler de ça.

En C ++, bien qu’ils aient une syntaxe similaire, les tableaux 2D ne sont PAS des tableaux en désordre. Les tableaux 2D ( double foo[681][24] ) sont alloués de manière contiguë en mémoire. Lorsque vous respectez un tableau 2D ( foo[j][i] ), il en fait * (foo + 24 * i + j). Tout cela se fait sous le capot. Le sizeof(foo)==sizeof(double)*681*24 .

Les tableaux dentelés sont ( double** bar; ). Il s’agit d’un groupe de tableaux différents: tout d’abord, vous allouez un tableau de pointeurs de 268 membres. Chaque pointeur indiquera un tableau de doublons de 24 éléments. La barre est juste un pointeur, donc sizeof(bar)==sizeof(void*) .

De manière plus gênante, les tableaux 2D (ou un tableau statique de toute dimension) se comportent de manière opposée à tous les autres types de C ++ dans le registre suivant: ils sont passés implicitement par référence, ce qui provoque le phénomène étrange ci-dessous.

 void foo(double bar[24][24]) { std::cout << sizeof(bar) << std::endl;} int main() { double test[24][24]; std::cout << sizeof(test) << std::endl;//returns sizeof(double)*24*24 foo(test);//returns sizeof(void*), implicitly passed by reference, opossite of the rest of c++! 

double[][] n’est pas la même chose que double** .

double** est un pointeur sur des pointeurs. double[][] est un tableau bidimensionnel alloué en tant que stockage continu.

Afin de passer un “tableau à 2 dimensions” à la fonction, vous devez créer un tableau de pointeurs sur les tableaux. Par exemple:

 double* array_2d[681]; for(unsigned int i=0; i<681; ++i) { array_2d[i] = new double[24]; } normalizeDataZeroMeanUnitSD(array_2d, 681, 24); 

N'oubliez pas de supprimer [] chaque élément de array_2d !

Mieux encore, changez normalizeDataZeroMeanUnitSD pour prendre une référence à std::vector> , sans avoir à vous soucier de la gestion de la mémoire, ni à transmettre les dimensions correctes à la fonction.