Speicher-Adresse in multidimensionalen Array ausrechnen (in C/C++)



  • Hallo, ich habe ein C/C++ Programm geschrieben, das Speicheradressen in n-dimensionalen Arrays ausrechnen soll. Vorgangsweise: Dope-Vektor mit Offsets erstellen, Index mit Offset in jeder Dimension multiplizieren und das zur Basis-Adresse des Arrays addieren. Mein Programm geht aber nicht,liefert falsche Adresse was mache ich falsch?

    #include <iostream>
    #include <vector>
    
    template <typename t>
    std::vector<int> create_dope_vector (int dim, std::vector<int> indices)
    {
    	std::vector<int> dp_vec;
    	int basis = sizeof(t);
    	int base = sizeof(t);
    
    	for (int i = 0; i < dim; ++i)
    	{
    		dp_vec.push_back(base/basis);
    		base *= indices[i];
    	}
    	return dp_vec;
    }
    
    template<typename t>
    t* adressof (t* ar, int dim, std::vector<int> indices, std::vector<int> sizes)
    {
    	t* adress = ar;
    	std::vector<int> dp_vec = create_dope_vector<t>(dim, sizes);
    	for (int i = 0; i < dim; ++i)
    	{
    		adress += indices[i] * dp_vec[i];
    	}
    
    	return adress;
    }
    
    int main()
    {
    	int a[4][3][2][6][4];
    	int * test_ptr = &a[3][1][0][0][2];
    	int* base_ptr = &a[0][0][0][0][0];
    	std::vector<int> sizes;
    	sizes.push_back(4); 
    	sizes.push_back(3);
    	sizes.push_back(2);
    	sizes.push_back(6);
    	sizes.push_back(4);
    	std::vector<int> indices_1;
    	indices_1.push_back(3); 
    	indices_1.push_back(1);
    	indices_1.push_back(0);
    	indices_1.push_back(0);
    	indices_1.push_back(2);
    
    	int* test_1 = adressof<int>(base_ptr, 5, indices_1, sizes);
    	std::cout << test_ptr << "\n";
    	std::cout << test_1 << "\n";
    	std::cout << test_2 << "\n";
    
    }
    

  • Mod

    Ungetestet: Sollten die Werte in Zeilen 8 und 9 nicht 1 sein? Zeigerarithmetik.

    edit: Nein, du teilst ja hinterher wieder durch base. Was aber zumindest heißt, dass du auch gleich 1 als Basis nehmen könntest und dir das Teilen sparen könntest.


  • Mod

    Entweder sind deine Indizes oder deine Rechnung falsch herum. Also entweder

    std::vector<int> sizes;
      sizes.push_back(4);
      sizes.push_back(6);
      sizes.push_back(2);
      sizes.push_back(3);
      sizes.push_back(4);
      std::vector<int> indices_1;
      indices_1.push_back(2);
      indices_1.push_back(0);
      indices_1.push_back(0);
      indices_1.push_back(1);
      indices_1.push_back(3);
    

    oder entsprechend deine Rechnung anders herum durchführen.



  • Danke für die Antwort, genau das wars. Hab vergessen, das C++ arrays nach row-first prinzip anordnet. Ich hab schon länger nicht mehr programmiert (mich wunderts das ich mich erinnert hab, wie Templates funktionieren. bereite mich jetzt auf Info-Studium nach Schule vor).

    Eine weitere Frage: Auf Wikipedia wird diese Formel für die Speicherabbildungsfunktion angegeben: https://de.wikipedia.org/wiki/Feld_(Datentyp)#Speicherabbildungsfunktion

    Kann mir wer die mathematische Notation, die dort für das Array verwendet wird, erklären? Ich mein das A[i\_1: k\_1] und so weiter.


  • Mod

    A[i:k] soll heißen, dass die Indizes von i bis k laufen. Das ist eine Verallgemeinerung gegenüber den speziellen Arrays in C++, bei denen i immer 0 ist.


Log in to reply