Was mache ich falsch mit pointer, array

OP #4807165
Lesenswert?
• ▲
▼
Hallo, ich verstehe nicht warum mein Programm zur Berechnung von 
Matrizen, keine größere Zeilenanzahl als 4 zulässt, ab zeile = 5 stürzt 
das Programm immer ab. Bei Zeilenwerten unter 5 funktioniert alles 
einwandfrei.
Über eine Antwort würde ich mich sehr freuen:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <time.h>
4

5
#define nl printf("\n");
6

7
//Hier werden der Matrix Werte übergeben(und hier ist wohl auch der Fehler:
8
void init(int **matrix, int zeile, int spalte){
9
  int zahl, eingabe, i, k;
10
  printf("Jeden Wert einzeln(0), oder nur mit einem einigen Wert initialisieren(1)"); nl
11
  scanf("%d", &eingabe);
12
  
13
//Jede Zahl einzeln initialisieren:
14
  if(eingabe==0){
15
    printf("Initialisiere die Matrix:"); nl
16
    for(i=0; i<zeile; i++ ){
17
      for(k=0; k<spalte; k++)  {
18
      scanf("%d", &zahl);
19
      matrix[i][k]=zahl;
20
      }
21
    }
22
//Mit nur einen Zahl initialisieren:
23
  }else{
24
    printf("Welche Zahl?"); nl
25
    scanf("%d", &zahl);
26
    for(i=0; i<zeile; i++ ){
27
      for(k=0; k<spalte; k++)  {
28
        matrix[i][k]=zahl;
29
//        printf(" %d ", i);        KOntrolle von i, mit dem Ergnis, das es gar nicht alle Spalten der 5. Zeile abgearbeitet werden
30
//        *(*(matrix+i)+k)=zahl;      Alternativschreibweise
31
      }
32
    }
33
  }
34
}
35
//Hier bekommen alle Werte einer Matrix den Wert 0:
36
void init_zero(int **matrix, int zeile, int spalte){
37
  int i, k;
38
  for(i=0; i<zeile; i++ ){
39
    for(k=0; k<spalte; k++)  {
40
    
41
    matrix[i][k]=0;
42
    }
43
  }
44
}
45
//Hier wird die Matrix ausgegeben:
46
printm(int **matrix, int zeile, int spalte){
47
  int i, k;
48
  
49
  for(i=0; i<zeile; i++ ){
50
    for(k=0; k<spalte; k++)  {
51
    printf("%d\t", matrix[i][k]);  
52
    }
53
    nl
54
  }
55
}
56
//Hier werden der Matrix Zufallswerte übergeben:
57
void init_random(int **matrix, int zeile, int spalte){
58
  int zahl, i, k;
59
  time_t t;
60
     srand((unsigned) time(&t));
61
     zahl=rand()%10;
62
  for(i=0; i<zeile; i++ ){
63
    for(k=0; k<spalte; k++)  { 
64
    zahl=rand()%10;
65
    matrix[i][k]=zahl;
66
    }
67
  }
68
}
69

70
//Hier bekommt die Matrix die Anzahl der Zeilen und Spalten:
71
int ** structm(int **matrix, int zeile, int spalte){
72

73
  int i;
74
  matrix=malloc(zeile*sizeof(int));
75
  if(matrix==NULL){
76
  printf("kein Speicherplatz vorhanden"); nl
77
  return 0;
78
  }  
79
  
80
  for(i=0; i<zeile; i++){
81
    matrix[i]=malloc(spalte*sizeof(int));
82
    if(matrix[i]==NULL){
83
  printf("kein Speicherplatz vorhanden"); nl
84
  return 0;      
85
    }
86
  }
87
  return matrix;
88
}
89
//Hier werden die 2 Matrizen multipliziert:
90
int multi(int **matrix, int **matrix2, int spalte, int zeile, int spalte2, int zeile2, int **result){
91
  if(spalte!=zeile2){
92
    printf("keine Multiplikation möglich");
93
    return 0;
94
    }
95

96
    int i, k, l;
97

98
    for (i = 0; i < zeile; i++) {  
99
        for (k = 0; k < spalte2; k++) {    
100
            for (l = 0; l < zeile2; l++) {  
101
                result[i][k] += matrix[i][l] * matrix2[l][k];  
102
            } 
103
    }
104
  }
105
  printm(result, zeile, spalte2);
106
  
107
  
108
  return 0;
109
}
110

111

112
int main(int argc, char *argv[]) {
113
  int spalte=0, zeile=0 , i;
114
  int spalte2=0, zeile2=0;
115
  int  **matrix;
116
  int  **matrix2;
117
  
118
  printf("Gebe die Spalten- und Zeilenanzahl ein:"); nl
119
  scanf("%d %d", &spalte, &zeile );
120
/*
121
  matrix=malloc(zeile*sizeof(int));
122
  if(matrix==NULL){
123
  printf("kein Speicherplatz vorhanden"); nl
124
  return 0;
125
  }  
126
  
127
  for(i=0; i<zeile; i++){
128
    *(matrix+i)=malloc(spalte*sizeof(int));
129
    if(matrix[i]==NULL){
130
  printf("kein Speicherplatz vorhanden"); nl
131
  return 0;      
132
    }
133
  }
134
*/  
135

136
//Abarbeitung der ersten Matrix
137
  matrix=structm(matrix, zeile, spalte);
138
  init(matrix, zeile, spalte);
139
  printm(matrix, zeile, spalte);
140
  nl
141
  
142
//Abarbeitung der zweiten Matrix  
143
  printf("Gebe die Spalten- und Zeilenanzahl ein:"); nl
144
  scanf("%d %d", &spalte2, &zeile2 );
145
  
146
  matrix2=structm(matrix2, zeile2, spalte2);
147
//  init_random(matrix2, zeile2, spalte2);
148
  init(matrix2, zeile2, spalte2);
149
  printm(matrix2, zeile2, spalte2);
150
  
151
  
152
//Multiplikationsmatrix
153
  int **result;
154
  result= structm(result, zeile, spalte2);
155
  init_zero(result, zeile, spalte2);
156
  
157
//  Multilpikation
158
  multi(matrix, matrix2, spalte, zeile, spalte2, zeile2, result);
159
  
160
  
161
  
162
  return 0;
163
}
Gruß
Antimonit

--

Bitte C-Quelltext in [ c ] [ /c ] einschließen.

-rufus
Persönliche Seite #4807175
Lesenswert?
• ▲
▼
1
//Hier bekommt die Matrix die Anzahl der Zeilen und Spalten:
2
int ** structm(int **matrix, int zeile, int spalte){
3

4
  int i;
5
  matrix=malloc(zeile*sizeof(int));
6
  if(matrix==NULL){
7
  printf("kein Speicherplatz vorhanden"); nl
8
  return 0;
9
  }  
10
  
11
  for(i=0; i<zeile; i++){
12
    matrix[i]=malloc(spalte*sizeof(int));
13
    if(matrix[i]==NULL){
14
  printf("kein Speicherplatz vorhanden"); nl
15
  return 0;      
16
    }
17
  }
18
  return matrix;
19
}

>   matrix=malloc(zeile*sizeof(int));


Das ist Murks. matrix ist kein int*, sondern ein int**, also ist hier 
sizeof int nur dann zufälligerweise korrekt, wenn sizeof int == sizeof 
int* ist.

Warum übergibst Du der Funktion den Parameter "matrix"? Was erhoffst Du 
Dir davon?


> #define nl printf("\n");


Gewöhn Dir das gleich wieder ab. Du kannst auch einfach \n an Deine 
Ausgaben anhängen, so, wie es der Rest der Welt auch macht.
OP #4807189
Lesenswert?
• ▲
▼
Okay, klingt einleuchtend, aber wie würde es dann korrekt aussehen?
Den Parameter "matrix" übergebe ich weil ich der Matrix Speicher 
zuweisen will.

Ist denn der Rest mit dem "int **matrix"(zum Beispiel bei den 
Funktionen) richtig, oder ist bei mir alles eher zufällig geglückt...für 
bestimmte Werte.

Okay, danke für den Hinweis beim "nl".
Persönliche Seite #4807215
Lesenswert?
• ▲
▼
David O. schrieb:
> Den Parameter "matrix" übergebe ich weil ich der Matrix Speicher
> zuweisen will.

Da Du die Variable mit dem Rückgabewert der Funktion überschreibst, geht 
das gut, aber es ist überflüssig und nutzlos, das als Parameter zu 
übergeben.

Wolltest Du tatsächlich den übergebenen Parameter verändern, müsstest Du 
a) den Rückgabewert der Funktion nicht an matrix zuweisen und b) einen 
Pointer auf matrix übergeben und den innerhalb Deiner Funktion 
dereferenzieren:
1
//aufruf
2

3
int** mm;
4

5
if (!structm(&mm, 3, 4))
6
{
7
  //fehlerbehandlung
8
}
9

10

11

12

13
//Hier bekommt die Matrix die Anzahl der Zeilen und Spalten:
14
int ** structm(int ***matrix, int zeile, int spalte)
15
{
16
  int i;
17

18
  *matrix = malloc(zeile * sizeof (int*));
19
  if (*matrix == NULL)
20
  {
21
    printf("kein Speicherplatz vorhanden\n");
22
    return 0;
23
  }  
24
  
25
  for (i = 0; i < zeile; i++)
26
  {
27
    *matrix[i] = malloc(spalte * sizeof (int));
28
    if (*matrix[i] == NULL)
29
    {
30
      printf("kein Speicherplatz vorhanden\n");
31
      return 0;      
32
    }
33
  }
34
  return *matrix;
35
}

Der Rückgabewert hat hier keinen weiteren Gebrauchswert als daß er im 
Erfolgsfall nicht 0 ist, was beim Aufruf entsprechend ausgewertet werden 
kann. Du könntest die Funktion daher auch irgendeinen anderen Typen als 
int** zurückgeben lassen, ein einfacher int würde reichen, der 0 bzw. 1 
annimmt.

Findest Du nicht auch, daß ein paar Leerzeichen den Code lesbarer 
machen?
OP #4807231
Lesenswert?
• ▲
▼
Rufus Τ. F. schrieb:
> Da Du die Variable mit dem Rückgabewert der Funktion überschreibst, geht
> das gut, aber es ist überflüssig und nutzlos, das als Parameter zu
> übergeben.
>
> Wolltest Du tatsächlich den übergebenen Parameter verändern, müsstest Du
> a) den Rückgabewert der Funktion nicht an matrix zuweisen und b) einen
> Pointer auf matrix übergeben und den innerhalb Deiner Funktion
> dereferenzieren:

Ja, danke, das stimmt...

Hab die Korrektur jetzt mal eingefügt(In der Funktion structm), jetzt 
geht allerdings gar nicht mehr, wo also hängts bei mir noch, der Rest 
sieht meiner Meinung nach richtig aus....bzw ich raff es nicht...

Rufus Τ. F. schrieb:
> Findest Du nicht auch, daß ein paar Leerzeichen den Code lesbarer
> machen?

Ja, da ist schon was dran :)
Moderator #4808151
Lesenswert?
• ▲
▼
Rufus Τ. F. schrieb:
> matrix->[i] = malloc(...)

Gaht das? Ich glaube nicht. Den "->"-Operator kann man in C doch nur auf
einen Struct-Pointer anwenden.

Rufus Τ. F. schrieb:
> aber das würde vermutlich wieder Leute auf die Barrikaden bringen, die C
> unlesbar finden.

Dafür wäre evtl. Folgendes ganz gut geeignet:
1
  i[*matrix] = malloc(...);

Damit spart man sich die runden Klammern in
1
  (*matrix)[i] = malloc(...);

was den Code deutlich kürzer und übersichtlicher macht ;-)

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