iconv crash



  • Hallo,

    folgender Code:

    int convutf8 (const char *in, char *out)
    {
    	size_t insize = strlen(in);
    	size_t avail = insize*4;
    	out = new char(avail);
    	memset(out,0,avail);
    
    	iconv_t cd = iconv_open ("utf-8", "ISO-8859-15");
    	if (cd == (iconv_t) -1){
    		if (errno == EINVAL)
    			std::cout<<"conversion from 8859-15 to utf8 not available"<<std::endl;
    		else
    			std::cout<<"error: iconv_open"<<std::endl;
    		*out = '\0';
    		return -1;
    	}
    
    	size_t inLeft=0;
    	size_t outLeft=0;
    	size_t nconv = iconv (cd, (char **)(&in), &inLeft, &out, &outLeft);
    	if (nconv == (size_t) -1){
    		std::cout<<"conversion from 88591 to utf8 ERROR"<<std::endl;
    	}
    
    	if (iconv_close (cd) != 0)
    		std::cout<<"error: iconv_close"<<std::endl;
    
    	return (nconv);
    }
    

    aufgerufen so:

    int Testfunc7()
    {
    	std::string str = readfile("8859-15.txt");
    	char* conv;
    	int ret = convutf8(str.c_str(), conv);
    ...
    }
    

    crasht (hier in Zeile 8, iconv_open()):

    (gdb) bt
    #0  0xb7fe1424 in __kernel_vsyscall ()
    #1  0xb7768401 in raise () from /lib/libc.so.6
    #2  0xb7769b42 in abort () from /lib/libc.so.6
    #3  0xb77a3815 in ?? () from /lib/libc.so.6
    #4  0xb77a96d1 in ?? () from /lib/libc.so.6
    #5  0xb77ac4fd in ?? () from /lib/libc.so.6
    #6  0xb77ae10c in malloc () from /lib/libc.so.6
    #7  0xb7755955 in ?? () from /lib/libc.so.6
    #8  0xb77554fc in iconv_open () from /lib/libc.so.6
    #9  0x0804adb2 in convutf8 (in=0x805293c "\344tzendes \326l  ", out=0x8052950 "") at ucTest/src/uct.cpp:353
    #10 0x0804bbb1 in Testfunc7 () at ucTest/src/uct.cpp:194
    #11 0x0804dc2a in main (argc=1, argv=0xbfffe5a4) at ucTest/src/uct.cpp:70
    

    Ich kommt nicht drauf wo mein Fehler ist. Habt ihre eine Idde?

    Danke + Grüße
    Mattes



  • Das hier:

    char* conv;
        int ret = convutf8(str.c_str(), conv);
    

    funktioniert nur, wenn conv als Referenz übergeben wird, was nicht der Fall ist. Ferner fordert das hier:

    out = new char(avail);
    

    Speicher für einen char an und initialisiert diesen mit dem Wert avail. Ansonsten muss inLeft, wenn ich das richtig im Kopf habe, bei Aufruf von iconv die Länge des zu konvertierenden Strings beinhalten, während outLeft die Größe des verfügbaren Ausgabepuffers beinhalten muss.

    Der konkrete Fehler wird aber wohl wegen des zweiten Problems auftreten. Mit

    memset(out,0,avail);
    

    zerschießt du dir den Heap, und als iconv_open Speicher anfordern will, kommt malloc damit nicht zurecht. Richtig wäre vorher

    out = new char[avail];
    


  • danke, recht hast du. Was hab ich da gestern fürn sch... geschrieben 🤡

    Hab das auch inzwischen schon selbst soweit gemerkt, funktioniert auch, nur das memset will noch nicht, das führt immer zu einem segfault beim delete...



  • nur das memset will noch nicht, das führt immer zu einem segfault beim delete...

    was auch nur an einem anderen dummen Fehler lag.

    Einen schönen Sonntag noch allerseits!


Anmelden zum Antworten