Forum: Compiler & IDEs Pointer-Array in C++


von Bastel B. (luoc)


Lesenswert?

Hi,
aus Gründen möchte ich mehrere Arrays oder wie im Beispiel zwei mit 
einem Array aus Pointern zusammenfassen. Allerdings gelingt mir die 
Umsetzung nicht. Hat jemand eine Idee wo der Fehler liegt?

Ich möchte alle Arrays in einer Schleife abarbeiten und dabei möglichst 
auf if-Abfragen verzichten (also genau die Ausdrücke, dich bei der 
Zuweisung / Ausgabe verwendet habe). Ist es also generell möglich sowas 
zu machen oder bin ich auf dem Holzweg?

Danke schonmal im Vorraus ;)
1
#include <iostream>
2
3
int main() {
4
5
  int s = 3;
6
  int *a = new int[s];
7
  int *b = new int[s];
8
  int *c = new int[2*s];
9
10
  // Arrays zuweisen
11
  for(int i=0; i<2*s; i++) {
12
    if(i<s) {
13
      c[i] = a[i];
14
    } else {
15
      c[i] = b[i-s];
16
    }
17
  }
18
19
  // Ausgangsarrays mit werten füllen
20
  for (int i=0; i<s; i++) {
21
    a[i] = i;
22
    b[i] = i+s;
23
  }
24
25
  // Ausgabe
26
  std::cout << "i\tist\tsoll" << std::endl;
27
  for(int i=0; i<2*s; i++) {
28
    std::cout << i << ":\t" << c[i] << '\t';
29
30
    if(i<s) {
31
      std::cout << a[i];
32
    } else {
33
      std::cout << b[i-s];
34
    }
35
36
    std::cout << std::endl;
37
  }
38
39
  return 0;
40
}

Bei der Zuweisung werden die Werte momentan direkt und nicht als Zeiger 
übergeben, dementsprechend sind alle Ausgaben 0.

Ausgabe:
1
i  ist  soll
2
0:  0  0
3
1:  0  1
4
2:  0  2
5
3:  0  3
6
4:  0  4
7
5:  0  5

von Klaus W. (mfgkw)


Lesenswert?

Sowohl deine Beschreibung als auch dein Quelltext erscheint mir etwas 
wirr,  aber eventuell willst du statt der beiden Felder a und b nur 
eines nehmen,  das doppelt so groß ist.  Dann machst du dir statt b nur 
einen Zeiger auf a[3]. Jetzt kannst du die oberen drei wahlweise als 
a[3] bis a[5] oder als b[0] bis b[2] ansprechen.
Mit einer Schleife über die sechs Elemente von a erreichst du also erst 
deine drei des bisherigen a und dann die drei von b.

Bei Bedarf kannst du entsprechend das Feld noch größer machen (12 
Elemente)  und c auch gleich mit unterbringen.  c wäre dann nur noch ein 
Zeiger auf a[6]. Ein Schleife über die 12 Elemente überstreicht dann 
deine 3 bisherigen a, dann die 3 b und dann die 6 c.

von Eric (Gast)


Lesenswert?

Du füllst erst dein Array c mit den Werten aus a und b und schreibst 
dann erst die Werte in a und b. Kein wunder, dass du dann nicht die 
neuen Werte in c hast.

Ich bin mir nicht sicher was du erreichen willst, aber auf jeden fall 
sind a, b und c int-Arrays (bzw Zeiger auf int, was aufs gleiche 
hinausläuft), du hast nirgendwo Arrays aus Pointern.

Ein Array aus Pointern wäre z.B.
1
int **c
oder
1
int *c[]

von Bastel B. (luoc)


Lesenswert?

@ Klaus Wachtler
Natürlich lässt sich mein Beispiel stark vereinfachen, ich möchte 
allerdings grundsätzlich klären, ob das so wie ich es mir vorstelle 
möglich ist. Den konkreten Anwendungsfall will ich jetzt nicht im Detail 
erklären, das sprengt den Rahmen.
Ich habe Daten unterschiedlicher Quellen, jeweils in einem eigenen 
Array. Der Einfachheit und der Performance halber will ich sie in der 
bearbeitenden Funktion aber als ein(!) Array darstellen und 
manipulieren, sie dabei aber am Ursprünglichen Speicherort belassen.

@ Eric
Das mein ursprünglich geposteter Code nicht das gewollte macht ist klar, 
habe ich ja auch dazugeschrieben ;). Allerdings läuft er.

Im Folgenden habe ich versucht ein Array mit Pointern vom Heap 
anzufordern, bekomme aber eine Fehlermeldung. Was mache ich falsch?
1
#include <iostream>
2
3
int main() {
4
  int s = 3;
5
  int *a = new int[s];
6
  int *b = new int[s];
7
  int **c = new *int[2*s]; // Fehlermeldung in dieser Zeile
8
9
  // Arrays zuweisen
10
  for(int i=0; i<2*s; i++) {
11
    if(i<s) {
12
      c[i] = &a[i];
13
    } else {
14
      c[i] = &b[i-s];
15
    }
16
  }
17
18
  // Ausgangsarrays mit werten füllen
19
  for (int i=0; i<s; i++) {
20
    a[i] = i;
21
    b[i] = i+s;
22
  }
23
24
  // Ausgabe
25
  std::cout << "i\tist\tsoll" << std::endl;
26
  for(int i=0; i<2*s; i++) {
27
    std::cout << i << ":\t" << c[i] << '\t';
28
29
    if(i<s) {
30
      std::cout << a[i];
31
    } else {
32
      std::cout << b[i-s];
33
    }
34
35
    std::cout << std::endl;
36
  }
37
38
  return 0;
39
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Statt diesem
1
  int **c = new *int[2*s]; // Fehlermeldung in dieser Zeile

dieses
1
  int **c = new int *[2*s]; // Fehlermeldung weg

Hier wird der Zeiger auf das jeweilige Element ausgegeben:
1
    std::cout << i << ":\t" << c[i] << '\t';

Willst du stattdessen den Inhalt, muss du "*" davor schreiben:
1
    std::cout << i << ":\t" << *c[i] << '\t';

von Bastel B. (luoc)


Lesenswert?

Manchmal ist es so einfach,
vielen lieben Dank Yalu X.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Du kannst die Arrays (bzw. die Speicherbereiche, auf die die drei
Pointer zeigen) auch folgendermaßen überlagern:
1
  int *c = new int [2*s];
2
  int *a = c;
3
  int *b = c + s;

Danach sind ist a[i] äquivalent mit c[i] und b[i] äquivalent mit c[s+i].

Die Frage ist allerdings, ob solche Array-Zugriffe "um die Ecke herum"
guter Stil sind. In alten Fortran-Programmen findet man dieses Konzept
recht häufig. In C++ gibt es dafür aber, je nach Anwendungsfall, evtl.
bessere Möglichkeiten.

von Mark B. (markbrandis)


Lesenswert?

Was spricht konkret dagegen, die in C++ typischen Standard-Konstrukte 
wie z.B. <array> oder <vector> zu verwenden?

Klar, man kann sowas auch von Hand ausprogrammieren. Eben so wie man es 
in C machen würde. Aber in C++ muss man das oftmals nicht. Wenn die 
Sprache mächtigere und weniger fehleranfällige Konstrukte bietet, dann 
sollte man diese auch verwenden.

l. o. schrieb:
> aus Gründen

Ach so, ja dann! ;-)

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.