Pointer-Array in C++

#3910339
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
#3910343
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.
Gast #3910344
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[]
#3910354
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
}
Moderator #3910373
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';
Moderator #3910415
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.
#3910551
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! ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren