Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Speicher freigeben

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
29.02.2008, 13:45 Uhr
~FreiherrEintritt
Gast


Ich reserviere für einen Matrix-Datentyp Speicher, den ich wieder freigeben will. So werden die Matrizen erzeugt bzw. freigegeben: (es sieht sehr umständlich aus, aber nur so schluckt es der mex-compiler von matlab...)


C++:
typedef struct matrix2 {
    int rows, cols;
    double **data;
    bool allocated;
} matrix2;


void createMatrix2(matrix2 *m, int r, int c)
{
    if(m->allocated == true) return;
    m->rows = r;
    m->cols = c;
    m->data = (double**)calloc(r, sizeof(double*));
    int i, j;
    for(i=0; i<r; i++) {
        m->data[i] = (double*)calloc(c, sizeof(double));
        for(j=0; j<c; j++) m->data[i][j] = 0;
    }
    m->allocated = true;
}


void freeMatrix2(matrix2 *m)
{
    if(m != 0) {
        if(m->allocated == false) return;
        int i;
        printf("free %d\n", m->rows);
        for(i=0; i<m->rows; i++) free(m->data[i]);
        free(m->data);
        m->allocated = false;
    }
}



Problem: freeMatrix2 funktioniert nur, solang die Anzahl der Zeilen nicht größer 3 wird, die Ausgabe "free 4" erscheint nie.

Hat jemand eine Idee, warum?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
29.02.2008, 13:50 Uhr
~FreiherrEintritt
Gast


Der Wert von m->rows hab ich in der Schleife mit free(m->data[i]) überprüft, er ist 4. Auch lässt sich auf alle 4 Elemente zugreifen, ohne einen Fehler zu erzeugen. Der Fehler tritt außerdem beim letzten Schleifendurchlauf auf: free(m->data[3]);
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
29.02.2008, 14:26 Uhr
Tommix



Hallo,
ich sehe keinen Fehler und kann es auch nicht nachstellen. Da das printf vor der Schleife mit dem free steht, muß das Problem weiter vorn sein (beim Aufruf?).
So läuft es bei mir:

C++:
int main()
{
    matrix2 m;
    m.allocated = false; // << Wichtig!
    createMatrix2(&m, 10, 10);
    m.data[9][9] = 1.234;
    freeMatrix2(&m);

    return 0;
}



Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
02.03.2008, 16:56 Uhr
~FreiherrEintritt
Gast


Die printf-Ausgabe steht nur hier vor der for-Schleife. Ich hatte sich auch schon darin, und zwar vor dem free, wodurch ich gesehen habe, dass der Fehler erst beim Löschen der Zeile 4 auftritt.
Das m.allocated = false ist auf jedenfall gewährleistet (sonst würde er ja schon beim Löschen der ersten Zeile meckern).

Mal was anderes: Ich hab schon ein funktionierendes Matrix-Gerüst, allerdings in C++. Wie kann ich mit der Option -c mit dem g++ kompilierte Object-Dateien mit dem gcc dazulinken? Ich würde die Schnittstelle in C99 halten und den Hintergrund in C++ auflaufen lassen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.03.2008, 00:21 Uhr
0xdeadbeef
Gott
(Operator)


Häng mal hinter die printf-Anweisung direkt ein fflush(stdout);, vielleicht hängt der Output noch im Buffer fest.

Übrigens, in createMatrix ist die Zeile

C++:
        for(j=0; j<c; j++) m->data[i][j] = 0;


überflüssig, calloc (im Gegensatz zu malloc) gibt genullten Speicher zurück.

Was das Linken von C-Code an C++-Module angeht, wenn du ein mit extern "C" deklariertes C-Interface exportierst, ist das überhaupt kein Problem. Natürlich können die exportierten Funktionssignaturen keine C++-spezifischen Dinge enthalten, wie etwa Klassen oder Exception-Spezifikationen, weil C damit nichts anfangen kann, es ist aber ohne weiteres möglich, etwas in der Art zu machen:

C++:
// c-compat.h
#ifndef INCLUDED_C_COMPAT_H
#define INCLUDED_C_COMPAT_H

#include <stddef.h>

#ifdef __cplusplus
extern "C"
#endif

typedef void *matrix_t;

matrix_t matrix_new(size_t x, size_t y);
void matrix_delete(matrix_t m);

#ifdef __cplusplus
}
#endif

#endif

// c-compat.cpp
#include "c-compat.h"
#include "matrix.hpp"

matrix_t matrix_new(size_t x, size_t y) {
  return reinterpret_cast<matrix_t>(new matrix(x, y));
}

void matrix_delete(matrix_t m) {
  delete reinterpret_cast<matrix*>(m);
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.03.2008, 08:02 Uhr
~FreiherrEintritt
Gast


Danke erstmal für die Ratschläge.
Das mit dem fflush kann ich jetzt von hier aus nicht ausprobieren, aber ich denke nicht, dass das der Grund ist, denn Matlab erzählt mir an dieser Stelle was von einem segmentation fault.
Und zu dem Linker-Problem: mit extern "C" kann ich C in C++ einbinden, ich bräuchte es aber anders rum. Ich will ja die Matrix-Berechnungen in C++ machen und das dann mit dem C-Compiler von Matlab einbinden.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.03.2008, 10:27 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


ne das steht doch genau so da:

die bibliothek kompilierst du mit einem externen c++-compiler, und bindest die dann über diesen c-kompatiblitätsheader wie deadbeef schon geschrieben hat mit deinem matlab c-compiler ein
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
03.03.2008, 12:18 Uhr
~FreiherrEintritt
Gast


Ich hab das mal an einem einfachen Beispiel getestet:

Die Datei testpp.cpp

C++:
#include <iostream>
using namespace std;

void printIt(char *s)
{
    cout << s << endl;
}


Kompiliert mit g++ testpp.cpp -o testpp -c
Funkioniert

Die Datei test.c:

C++:
#include "kompa.h"

int main()
{
    char s[] = "Test";
    printIt(s);
    return 0;
}



Und kompa.h:

C++:
#ifndef __KOMPA_H__
#define __KOMPA_H__

#include <stddef.h>

#ifdef __cplusplus
extern "C"
#endif

void printIt(char *s);

#endif



Kompiliert mit gcc test.c testpp -o test. Den Teil mit

C++:
#ifdef __cplusplus
}
#endif


musste ich weglassen, weil er das nicht akzeptiert.

Jetzt kommt folgende Fehlermeldung:
testpp: In function `__static_initialization_and_destruction_0(int, int)':
testpp.cpp.text+0x23): undefined reference to `std::ios_base::Init::Init()'
testpp: In function `__tcf_0':
testpp.cpp.text+0x6c): undefined reference to `std::ios_base::Init::~Init()'
testpp: In function `printIt':
testpp.cpp.text+0x82): undefined reference to `std::cout'
testpp.cpp.text+0x87): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<<

usw.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
03.03.2008, 13:15 Uhr
0xdeadbeef
Gott
(Operator)


Eh, Tipfeeler meinerseits. Das muss

C++:
#ifdef __cplusplus
extern "C" {
#endif


sein, dann klappts auch mit dem

C++:
#ifdef __cplusplus
}
#endif


Außerdem muss die Übersetzungseinheit, in der die Funktion definiert wird, den c-compat-Header einbinden, damit die Funktion auch weiß, dass sie extern "C" ist.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 03.03.2008 um 13:16 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
03.03.2008, 15:45 Uhr
~FreiherrEintritt
Gast


Also ist der Trick quasi, zu exportierende Symbole im C++ Bereich mit extern "C" zu deklarieren, damit sie in C ohne Umstände angesprochen werden können?
Leider kommt aber die selbe Fehlermeldung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: