ooohhh ja klar, an sowas hatte ich garnicht gedacht. vielen dank für deine schnelle hilfe ☺
ne, sprintf reicht, weil in dem speicherbereich nur eine mysql-id abgelegt werden soll und das damit sowieso begrenzt ist...
Anmeldungsdatum: Beiträge: Zähle... |
ooohhh ja klar, an sowas hatte ich garnicht gedacht. vielen dank für deine schnelle hilfe ☺ ne, sprintf reicht, weil in dem speicherbereich nur eine mysql-id abgelegt werden soll und das damit sowieso begrenzt ist... |
Anmeldungsdatum: Beiträge: 3620 |
Ich sehe gerade, dass da ein Fehler in meinem Code war. Statt char yeahaaa = "yeahaaaaaaaa"; muss es natürlich char yeahaaa[] = "yeahaaaaaaaa"; |
Anmeldungsdatum: Beiträge: 5 |
hm, also das testprogramm funktioniert jetzt soweit, ich benutze übrigens strcpy, damit der zeiger nicht auf den konstanten string gesetzt wird. Das ganze habe ich jetzt auf das richtige programm übersetzt, aber da funktioniert es nichtmehr, und ich sehe einfach keinen grund, wieso es nicht funktioniert. Hier einmal die wie ich denke relevanten codestellen: char **mysql_players; short int *player_team; char **player_names; //[....] inline int init(char *config_file) { //[......] game_id = malloc(100); input_line_time = 0; input_line = malloc(2000); players_invalid = 0; player_join_time = malloc(sizeof(unsigned long int) * max_players); map_id = malloc(100); map_start = 0; game_mode = DM; player_clan = malloc(sizeof(unsigned long int) * max_players); player_modifier = malloc(sizeof(float) * max_players); player_names = malloc(sizeof(char*) * max_players); player_pickup_id = malloc(sizeof(char*) * max_players); player_team = malloc(sizeof(short int) * max_players); player_voted = malloc(sizeof(short int) * max_players); players = 0; player_pickups = malloc(sizeof(int*) * max_players); mysql_players = (char**)malloc(sizeof(char *) * max_players); int i = 0; for(; i < max_players; i++) { player_clan[i] = 0; player_modifier[i] = 0; player_names[i] = malloc(200); player_pickup_id[i] = malloc(100); player_team[i] = UNDEFINED_TEAM; player_voted[i] = 0; mysql_players[i] = (char*)malloc(500); printf("before\n"); strcpy(mysql_players[i], "0"); printf("success\n"); int n=0; for(; n < 9; n++) player_pickups[i][n] = 0; } strcpy(player_names[0], "blubba"); printf("player_names\n"); strcpy(mysql_players[0], "bu"); printf("mysql_players\n"); return 0; } int main(int argc, char **argv) { printf("blubba\n"); if(argc == 1) { printf("ERROR: please start this program like this: %s teeworlds-server-config.cfg", argv[0]); exit(2); } printf("-1\n"); init(argv[1]); printf("init ready"); //[.......] }
blubba -1 1 before success before success before success before success before success before success before success before success before success before success player_names [1] 5412 segmentation fault (core dumped)
|
Anmeldungsdatum: Beiträge: 3620 |
Du initialisierst mysql_players nirgends und versuchst dann, mit strcpy etwas nach mysql_players[0] zu schreiben - klar, dass das nicht funktioniert. Übrigens würde ich Dir dringend empfehlen, die ganzen Informationen über Spieler in ein struct zu packen. Sowas hier ist nämlich einfach grauenhaft: player_clan = malloc(sizeof(unsigned long int) * max_players); player_modifier = malloc(sizeof(float) * max_players); player_names = malloc(sizeof(char*) * max_players); player_pickup_id = malloc(sizeof(char*) * max_players); player_team = malloc(sizeof(short int) * max_players); player_voted = malloc(sizeof(short int) * max_players);
calloc(max_players, sizeof(struct player)); Übrigens sind statements der Form malloc(foo*bar) generell gefährlich, da immer Integer Overflows auftreten können, die dann zu einem eventuell sicherheitskritischen Buffer Overflow führen können. Offen gestanden halte ich es für völlig verfehlt, dass Du ausgerechnet C für Dein Projekt verwenden willst. Nutze Python oder Java oder C# oder so etwas, aber doch nicht so ein Rudiment aus den 70ern wie C. |
Anmeldungsdatum: Beiträge: 5 |
hm, jo, das mit dem struct mache ich wohl mal, danke aber ich deklariere und initialisiere mysql_players doch, oder muss ich da noch was anderes beachten?: mysql_players = (char**)malloc(sizeof(char *) * max_players); mysql_players[i] = (char*)malloc(500); printf("before\n"); strcpy(mysql_players[i], "0");
jo, das projekt ist in der jetzigen version in java, aber da es mit einem server laufen soll, ist es unpraktisch, dass das java-programm mindestens 15mb ram braucht. meist sind sogar von dem programm 40mb belegt. und wieso C#, funktioniert das nicht nur unter windows? ich finde c schön, außer dass ich noch nicht viel weiß. |
Anmeldungsdatum: Beiträge: 3620 |
Oh, die Initialisierung von mysql_players hatte ich übersehen, Entschuldigung. So auf die Schnelle kann ich kein Problem erkennen, wahrscheinlich fehlt die relevante Stelle im Quellcode. Bitte stell ein Programm zusammen, das
Dann kann man Dir helfen. |
![]() Anmeldungsdatum: Beiträge: 2999 Wohnort: OS |
Mal abgesehen davon, ob nun C die richtige Sprachwahl ist oder nicht: Du schreibst schon einen etwas gewöhnungsbedürftigen Code. Beispielsweise: struct Playerinfo{ char *cPlayerName; [...] }; [...] struct Playerinfo *Player; Player=(struct *Playerinfo) malloc(sizeof *Player); [...] Player->cPlayerName=(char *) malloc(sizeof MAXLENGTH); [...] strcpy(Player->cPlayerName, "L33t"); Und zur Not gibt's noch typedefs, dann kannst Du Konstrukte wie "(struct *Playerinfo)" vereinfachen zu bspw. "(PLAYER *)".
Warum nicht gleich for(i=0; i < max_players; i++) Geht sowas überein? mysql_players = (char**)malloc(sizeof(char *) * max_players); [...] mysql_players[i] = (char*)malloc(500); [...] strcpy(mysql_players[0], "bu"); Wenn Du (char *) reservierst, kannst Du nachher nicht nochmal das Element mit (char *) belegen. mysql_players[i]=malloc (500) Das
sollte wohl auch eher player_names =(char **) malloc(sizeof(char*) * max_players);
Du willst ja ein Feld für die Namen dynamisch reservieren der Art player_names[0]="L33t"; player_names[1]="c00LK!ll4"; [...] P.S.: Sicherer wäre es, alle Längenangaben und Reservierungen überprüfen zu lassen 😉 |
Anmeldungsdatum: Beiträge: 3620 |
lilith2k3, Dein C-Code ist auch nicht besser. malloc liefert einen void* zurück, daher ist es unnötig und sogar schädlich, den Rückgabewert von malloc zu casten. Das hier ist überhaupt kein gültiger Typ in C: Was soll das hier: struct Playerinfo { char Name[MAXLENGTH]; }; ? for(i=0; i < max_players; i++)
|
![]() Anmeldungsdatum: Beiträge: 2999 Wohnort: OS |
Okay, die Fehler sind dumm! Aber
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { char **mysqlplayers; int i; mysqlplayers=(char **) malloc (sizeof (char *) *3); for (i=0; i < 3; i++) { mysqlplayers[i]=malloc(12); } for (i=0; i < 3; i++) { strcpy(mysqlplayers[i], "bu"); } for (i=0; i < 3; i++) { printf("%s\n", mysqlplayers[i]); } for (i=0; i < 3; i++){ free(mysqlplayers[i]); } free(mysqlplayers); return (0); } Das tut was es soll. Ich les' mir den Link nachher in Ruhe durch. |
![]() Anmeldungsdatum: Beiträge: 2999 Wohnort: OS |
Okay, wieder was gelernt! Das Casting kann also eventuelle Probleme verdecken; auch wenn ich das malloc-Beispiel in dem Text ein wenig an den Haaren herbeigezogen finde. Wenn die Funktion einen falschen Rückgabewert liefert (wie in dem Beispiel angegeben, die "unbekannte" malloc-Funktion einen int) ist das Ergebnis selbstverständlich äußerst dubios und das Casting verdeckt das. Dann sollte eigentlich der Fehler im obigen Code von scosu nachwievor bei: mysql_players[i] = (char*)malloc(500);
|
Anmeldungsdatum: Beiträge: 5792 |
lilith2k3 hat geschrieben:
Ist es dir noch nie passiert, dass du irgendwo mal ein #include vergessen hast? 😉 |
![]() Anmeldungsdatum: Beiträge: 2999 Wohnort: OS |
Mir ist heute (s.o.) schlimmeres passiert *g* |
Anmeldungsdatum: Beiträge: 3620 |
lilith2k3 hat geschrieben:
Wieso denn? Er allokiert doch Speicher, in den er später einen String kopieren will, daher sollte letzteres auch keine Probleme machen. |
Anmeldungsdatum: Beiträge: 5 |
vielen dank für eure hilfe, also habe da nicht weiter geforscht woran es lag, sondern wie ihr gesagt habt umgeschrieben zu einem array von player structs und das funktionierte von anfang an wunderbar. und sieht natürlich jetzt auch schöner aus ☺. ich wusste garnicht dass das casten probleme machen kann, in einem tutorial stand, dass man es machen soll für kompatibilität zu c++ oder so, aber dann lasse ich das in zukunft lieber 😉 |
Anmeldungsdatum: Beiträge: 3620 |
Kompatbilität mit C++-Compilern ist überhaupt kein Argument. Wenn man C++ schreibt, dann allokiert man seinen Speicher mit new, nicht mit malloc. Wenn man C schreibt, dann gibt es keinen Grund für den Cast. Und wenn C-Funktionen von einem C++-Programm aus aufgerufen werden sollen, dann bindet man die mit extern "C" ein. |