Malloc - Fehler

OP #4847659
Hallo,
ich habe ein Problem mit der dynamischen Speicherverwaltung. Es 
reserviert mehr Speicherplatz als ich vorhabe
1
#include <stdio.h>
2
#include <stdlib.h>
3
#define GROESSE_FELD 4
4
#define DIM_ZEILE GROESSE_FELD * 2+1
5
#define DIM_SPALTE GROESSE_FELD * 2+1
6

7

8
void spielGeruest(char **spielfeld){
9
int i=0, j=0;
10

11
for (i=0;i<(DIM_ZEILE); i++){
12
    for(j=0;j<(DIM_SPALTE);j++){
13
        if(!(i%2)){
14
            if(!(j%2)){
15
                spielfeld[i][j]='|';
16
        }
17
        else{
18
            spielfeld[i][j]='-';
19

20
        }
21
        }
22
        else{
23
            if(!(j%2)){
24
                spielfeld [i][j]='|';
25
            }
26
            else{
27
                spielfeld [i][j]='x';
28
            }
29
        }
30
    }
31
}
32
}
33

34
void ausgabeSpielfeld(char **spielfeld){
35

36
}
37
int main(){
38
    char **Feld;
39
    int i;
40
    Feld=(char**)malloc(sizeof(char*)* DIM_ZEILE);
41
    for(i=0;i<DIM_SPALTE;i++){
42
        Feld[i]=(char*)malloc(sizeof(char)* DIM_SPALTE);
43
}
44
spielGeruest(Feld);
45
printf("%s",*(Feld+1));
46
}

Zusätzlich zum String gibt er mir noch mehr Zeichen aus.

Warum?

MfG
Persönliche Seite
Daniel S. schrieb:
> Feld[i]=(char*)malloc(sizeof(char)* DIM_SPALTE);

Das macht nicht das, was Du erwartest.

> sizeof(char)* DIM_SPALTE

Wieviel mag das sein?

> #define GROESSE_FELD 4
> #define DIM_SPALTE GROESSE_FELD * 2+1

Also:

> sizeof (char)  4  2 + 1


Durch die Verwendung von Klammern im #define-Ausdruck ließe sich das 
Problem beseitigen.


Davon abgesehen

> Feld=(char**)malloc(sizeof(char*)* DIM_ZEILE);
> for(i=0;i<DIM_SPALTE;i++){
>   Feld[i]=(char*)malloc(sizeof(char)* DIM_SPALTE);

ist hier das Schleifenabbruchkriterium falsch, da sollte nicht 
DIM_SPALTE, sondern DIM_ZEILE stehen. Das macht hier zwar nichts, da 
beide gleich groß sind, aber wenn sie es nicht mehr sind (weil die 
Feldgrößen geändert werden), knallts.


Im übrigen wird C-Sourcecode durchaus lesbarer, wenn man an sinnvollen 
Stellen Leerzeichen zur Trennung verwendet:

> Feld = (char **) malloc(sizeof (char *) * DIM_ZEILE);
> for (i = 0; i < DIM_SPALTE; i++)
> {
>   Feld[i] = (char *) malloc(sizeof (char) * DIM_SPALTE);

Die beiden Typecasts sind in C übrigens überflüssig; malloc gibt void* 
zurück, das lässt sich beliebigen Pointertypen zuweisen.
Und sizeof(char) ist per Definition immer 1.
Generell bietet es sich aber an, bei Malloc einfach das Zeigerziel des 
Ergebnisses für die Größe herzunehmen:
1
Feld = malloc(DIM_ZEILE * sizeof *Feld);
2

3
Feld[i] = malloc(DIM_SPALTE * sizeof **Feld);

So sind sämtliche Größen der Typen bei den mallocs nur noch davon 
abhängig, wie Feld definiert ist statt "hart codiert". Solltest du 
später mal auf die Idee kommen, aus den chars doch shorts oder gar 
structs zu machen, passt der Code ohne Änderung.
Gast
Das hier
> #define DIM_ZEILE GROESSE_FELD * 2+1

und das hier
>     Feld=(char**)malloc(sizeof(char*)* DIM_ZEILE);

passt nicht gut zusammen.

Man schreibt die Klammern im #define (und nicht dort, wo die Konstante 
benutzt wird) und zwar genau deshalb, damit der Wert nicht den 
Vorrangregeln von Operatoren gestört wird:
1
sizeof(char*)* GROESSE_FELD * 2+1
ist nämlich was ganz anderes als
1
sizeof(char*)* (GROESSE_FELD * 2+1)
Tip: Man kann in c auch solche Dinge tun:
1
#include <stdio.h>
2

3
int main(){
4
  printf("%u\n",sizeof(int[5][2]));
5
  return 0;
6
}
Oder sowas:
1
#include <stdio.h>
2

3
int main(){
4
  const int a=5;
5
  const int b=2;
6
  printf("%u\n",sizeof(int[a][b]));
7
  return 0;
8
}
Noch ein Trick, den ich gerne anwende:
1
#include <stdio.h>
2

3
void func( const int x, const int y, int buf[y][x] ){
4
  buf[1][3] = 42;
5
}
6

7
int main(){
8
  const int x=5, y=2;
9
  int buf[y][x];
10
  func(x,y,buf);
11
  printf("%d\n",buf[1][3]);
12
  return 0;
13
}

Die Vorteile hier sind, dass man sich nirgens verrechnen kann und es 
kein malloc gibt das fehlschlagen könnte. Ein nachteil ist, dass es yu 
einem Stackoverflow kommen kann, wenn buf zu gross ist.
OP
Okay perfekt. Vielen Dank schon einmal für eure umfassende Hilfe :). 
Habe den Großteil schon ausgebessert.

Eine Frage hätte ich jedoch noch. Und zwar will ich in einem String den 
Wert einer Variablen abspeichern. Wie geht das?

Kenne nur die Möglichkeiten mit "..." und '...' konstante Werte 
abzuspeichern. Aber sowas wie str1[0][0]=x;
geht nicht ....

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.