String an Funktion übergeben

G

gruenpflanze

Mitglied
Hallo!
Erstmal vorweg, weshalb ist die Textverarbeitung (string, char, input-methoden) eigentlich so kompliziert unter C++? Oder kommt nur mit das so kompliziert vor?

Folgendes vereinfachtes Programm soll mein Problem zeigen:
Ich habe eine string Variable, die ich an eine Funktion übergeben will damit diese verarbeitet werden kann.

Code:
#include <iostream>
#include <string>
using namespace std;
string test(string hallo); //deklarierung der Funktion
string hallo="hehey"; 
int main()
{
test(hallo); //test wird aufgerufen und hallo übergeben.
}

string test(string hallo)
{
cout << ""<<hallo;
}

Der Output schaut so aus:
*** glibc detected *** ./a.out: free(): invalid pointer: 0xbfff980c ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7dc47cd]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7dc7e30]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7f86d11]
/usr/lib/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1d)[0xb7f63a5d]
/usr/lib/libstdc++.so.6(_ZNSsD1Ev+0x57)[0xb7f665e7]
./a.out(__gxx_personality_v0+0x245)[0x8048979]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xdc)[0xb7d72ebc]
./a.out(__gxx_personality_v0+0x4d)[0x8048781]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:02 4620295 /home/michael/maturaarbeit/tests/a.out
08049000-0804a000 rw-p 00000000 08:02 4620295 /home/michael/maturaarbeit/tests/a.out
0804a000-0806b000 rw-p 0804a000 00:00 0 [heap]
b7c00000-b7c21000 rw-p b7c00000 00:00 0
b7c21000-b7d00000 ---p b7c21000 00:00 0
b7d5c000-b7d5d000 rw-p b7d5c000 00:00 0
b7d5d000-b7e98000 r-xp 00000000 08:02 2428132 /lib/tls/i686/cmov/libc-2.5.so
b7e98000-b7e99000 r--p 0013b000 08:02 2428132 /lib/tls/i686/cmov/libc-2.5.so
b7e99000-b7e9b000 rw-p 0013c000 08:02 2428132 /lib/tls/i686/cmov/libc-2.5.so
b7e9b000-b7e9e000 rw-p b7e9b000 00:00 0
b7e9e000-b7ea9000 r-xp 00000000 08:02 2424896 /lib/libgcc_s.so.1
b7ea9000-b7eaa000 rw-p 0000a000 08:02 2424896 /lib/libgcc_s.so.1
b7eaa000-b7eab000 rw-p b7eaa000 00:00 0
b7eab000-b7ed0000 r-xp 00000000 08:02 2428140 /lib/tls/i686/cmov/libm-2.5.so
b7ed0000-b7ed2000 rw-p 00024000 08:02 2428140 /lib/tls/i686/cmov/libm-2.5.so
b7ed2000-b7fb1000 r-xp 00000000 08:02 2132136 /usr/lib/libstdc++.so.6.0.8
b7fb1000-b7fb4000 r--p 000de000 08:02 2132136 /usr/lib/libstdc++.so.6.0.8
b7fb4000-b7fb6000 rw-p 000e1000 08:02 2132136 /usr/lib/libstdc++.so.6.0.8
b7fb6000-b7fbc000 rw-p b7fb6000 00:00 0
b7fc8000-b7fcb000 rw-p b7fc8000 00:00 0
b7fcb000-b7fe4000 r-xp 00000000 08:02 2424853 /lib/ld-2.5.so
b7fe4000-b7fe6000 rw-p 00019000 08:02 2424853 /lib/ld-2.5.so
bffe5000-bfffa000 rw-p bffe5000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
heheyAborted (core dumped)

Ich vermute, dass es am Gültikeitsbereich der Stringvariable liegt. Kann es sein, dass der Pointer in der Funktion schon ins Leere zeigt? Bin mit der Fehlermeldung überfordert.
Vielen Dank!
Ach ja, der Fehler wird zur laufzeit ausgegeben, d.h. das kompilieren mit c++ (unter debian) hat funktioniert.

Danke!
 
Also an dem Programm ist eigentlich alles einwandfrei in Ordnung.
Ausgabe sieht aus wie folgend:

Kompiliert mit "g++ (GCC) 4.1.3 20070812 (prerelease) (Debian 4.1.2-15)".
 
Und weil du den string global deklariert hast solltest du im unterprogramm auch ohne übergabe drauf zugreifen können.

Sehr sauber ist die verwendung von globalen variablen allerdings nicht.
 
Code:
*@debian:~/maturaarbeit/tests$ [B]gcc string.cpp[/B]
string.cpp:14:2: warning: no newline at end of file
/tmp/ccOHo2y4.o: In function `__tcf_1':
string.cpp:(.text+0xe): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/tmp/ccOHo2y4.o: In function `__static_initialization_and_destruction_0(int, int)':
string.cpp:(.text+0x40): undefined reference to `std::ios_base::Init::Init()'
string.cpp:(.text+0x67): undefined reference to `std::allocator<char>::allocator()'
string.cpp:(.text+0x82): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
string.cpp:(.text+0x8d): undefined reference to `std::allocator<char>::~allocator()'
string.cpp:(.text+0xbc): undefined reference to `std::allocator<char>::~allocator()'
/tmp/ccOHo2y4.o: In function `__tcf_0':
string.cpp:(.text+0xfa): undefined reference to `std::ios_base::Init::~Init()'
/tmp/ccOHo2y4.o: In function `test(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
string.cpp:(.text+0x111): undefined reference to `std::cout'
string.cpp:(.text+0x116): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
string.cpp:(.text+0x127): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/tmp/ccOHo2y4.o: In function `main':
string.cpp:(.text+0x151): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
string.cpp:(.text+0x171): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
string.cpp:(.text+0x17c): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
string.cpp:(.text+0x197): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/tmp/ccOHo2y4.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld gab 1 als Ende-Status zurück
 
...
Kompiliert mit "g++ (GCC) 4.1.3 20070812 (prerelease) (Debian 4.1.2-15)".

gcc ist der C compiler g++ ist der C++ compiler.

Das Packet gcc steht überigens nicht mehr für Gnu C Compiler, sondern gür Gnu Compiler Collection, deswegen kanns leicht sein, dass ein Neuling verwirrt wird, lass dich davon nicht zurückwerfen.
 
gcc ist der C compiler g++ ist der C++ compiler.

Das Packet gcc steht überigens nicht mehr für Gnu C Compiler, sondern gür Gnu Compiler Collection, deswegen kanns leicht sein, dass ein Neuling verwirrt wird, lass dich davon nicht zurückwerfen.
Danke.
Aber auch mit dem Compiler "c++" oder "g++" oder was es sonst noch alles gibt auf einer linux-maschine geht es nicht. Siehe 1. Post.
An was könnte es noch liegen? Hat jemand eine Idee?
 
Deine test()-Funktion ist falsch. Sie gibt nämlich keinen String zurück, obwohl sie es laut Deklaration tun muss.

Kleiner Tipp: benutze beim kompilieren -Wall als Parameter.


Mfg,
Lord Kefir
 
Deine test()-Funktion ist falsch. Sie gibt nämlich keinen String zurück, obwohl sie es laut Deklaration tun muss.
Das ist so natürlich richtig, es sollte aber nicht zu dem Fehler führen, wie es das bei ihm tut.
Wenn ich mich recht erinnere ist es nach dem ISO-Standard übrigens erlaubt in einer Funktion entgegen der Funktionsdeklaration keinen Wert zurückzugeben, es führt allerdings zu undefiniertem Verhalten, wenn man den Wert, den die Funktion dann zurückgibt benutzt.
 
Das ist so natürlich richtig, es sollte aber nicht zu dem Fehler führen, wie es das bei ihm tut.
Wenn ich mich recht erinnere ist es nach dem ISO-Standard übrigens erlaubt in einer Funktion entgegen der Funktionsdeklaration keinen Wert zurückzugeben, es führt allerdings zu undefiniertem Verhalten, wenn man den Wert, den die Funktion dann zurückgibt benutzt.

Ich lasse mich jetzt nicht auf eine C++-Diskussion ein, weil ich zwar in diversen Sprachen programmiere, aber nicht in C++ ;)

Ich fände es auch krass, wenn es wirklich nur daran liegen sollte. Bei mir klappt's aber mit einer void-Deklaration - oder wenn test() einen String zurückgibt:
Code:
#include <iostream>
#include <string>
using namespace std;

string hallo="123";
string test(string hallo);
int main() {	
	test(hallo);
}

string test(string hallo)
{
	string x;
	cout<<""<< hallo;
	return x;
}

Der Rest des Codes sieht schließlich korrekt aus.


Mfg,
Lord Kefir
 
$ g++ string.cc -Wall
string.cc: In function 'std::string test(std::string)':
string.cc:14: warning: control reaches end of non-void function
stimmt schon das hat er nicht gern, wundert mich eigentlich, dass er das warning nicht auch ohne wall ausgibt

Ich finds cool, dass es bei dir mit einem return value geht, ich muss lediglich
Code:
string hallo="hehey\0";
einbauen, dass es funktioniert, wenn ich das nicht drinnen hab auch ein segfault, aber das ist durchaus begründet.

Ich find das aber ziemlich cool, weil die version von Lord Kefir bei mir auch wunderbar läuft, obwohl du auch keine stringterminierung eingebaut hast. Nur rein verständnishalber, muss man das "\0" in c++ strings einbauen?

Btw Lord Kefir wenn ich bei deinem Programm den return wert weggeb funktionierts auch nicht, auch nicht wenn ich das "\0" als stringterminierung in die initialisierung schreib.:think:

Mir kommt das ganze ziemlich suspekt vor.

Kompiliert mit g++ (GCC) 4.1.2 (Gentoo 4.1.2)
 
Mir kommt das ganze sehr merkwürdig vor, es scheint ja kein Fehler im Code zu sein.
gruenpflanze, hast du mal den Debugger angeworfen und nachgesehen, wo genau das Programm abbricht?
[..]wenn ich das nicht drinnen hab auch ein segfault, aber das ist durchaus begründet.
Ich verstehe nicht, warum?

Ich find das aber ziemlich cool, weil die version von Lord Kefir bei mir auch wunderbar läuft, obwohl du auch keine stringterminierung eingebaut hast. Nur rein verständnishalber, muss man das "\0" in c++ strings einbauen?

Code:
"blahblah"; /* Ist ein null-terminierter String, in C wie in C++. */
 
Code:
"blahblah"; /* Ist ein null-terminierter String, in C wie in C++. */

Stimmt jetzt kommts mir erst mich wunderts trotzdem, dass es mit der "zweiten" terminierung dann hinhaut, aber egal deswegen heists ja nicht definiert.

Also im endeffekt kommen wir zu dem ergebnis, dass die beendigung einer non void funktion ohne return wirklich nicht definiert ist?

wenn ich das nicht drinnen hab auch ein segfault, aber das ist durchaus begründet.
war aufs "\0" bezogen, hat sich damit aber auch erledigt
 
Ich habe hier gerade auf der Arbeit versucht den Code mit Visual Studio zu kompilieren - und siehe da: es geht nicht.

Liegt definitiv am Rückgabewert.


Mfg,
Lord Kefir
 
Zuletzt bearbeitet:

Ähnliche Themen

serdisplib C++ double free or corruption

Fehlermeldung beim SSH-Login / Server nicht mehr erreichbar

Samba 4 Gast Zugang unter Ubuntu funktioniert nicht

Festplatte stirbt, dd funktioniert nicht

Ubuntu X / dbus problem

Zurück
Oben