Ich habe ein Kommandozeilen-Spiel schrieb ich, dass lokal korrekt ausgeführt wird, aber segfaults auf einem Remote-Server. Ich habe nicht herausgefunden, warum das so ist.C-Programm läuft gut lokal, aber segFaults auf Remote-Server
Local:
Sender:
Es ist eindeutig ein Problem irgendwo, wo mögliche Verbindungen gesammelt werden/angezeigt.
Hier ist das volle Programm. Dieses Problem tritt möglicherweise um Zeile 190 auf, da sich hier die Logik MÖGLICHE VERBINDUNGEN befindet. Ich habe das Gefühl, dass es ein Problem mit meiner strncpy
Linie ist, da dort sehr spezifische Speichermanipulation stattfindet, aber ich könnte falsch liegen.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
struct stat st = {0};
const char * ROOM_NAMES[] = {"Water", "Fire", "Wind", "Earth", "Plasma", "DarkMatter", "Air", "Ice", "Rock", "Lava"};
int i,j;
char directory[20];
char *rooms[7];
int connections[7][7] = {0};
int totalMoves = 0;
char roomChoice[20];
char *movesRecord[100];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void getRoomChoice() {
fflush(stdin);
scanf("%s", roomChoice);
fflush(stdin);
fflush(stdout);
}
void * getTime(void *arg) {
pthread_mutex_lock(&mutex);
FILE *file = fopen("currentTime.txt", "w");
time_t curtime;
struct tm *loc_time;
curtime = time (NULL);
loc_time = localtime (&curtime);
fprintf(file, "%s\n", asctime (loc_time));
// printf("\n%s\n", asctime (loc_time));
fclose(file);
pthread_mutex_unlock(&mutex);
}
void * createRooms() {
// Create directory
int pid = getpid();
char prefix[] = "eldridgt.";
sprintf(directory, "%s%d", prefix, pid);
if (stat(directory, &st) == -1) {
mkdir(directory, 0700);
}
// Create room files
for(i=0; i<7; i++) {
int random;
char filePath[100];
int connectionArr[10];
memset(connectionArr, 0, sizeof connectionArr);
random = rand() % 10; // Random number 0-9
if (connectionArr[random] == 0) { // If room not used
sprintf(filePath,"%s/%s", directory, ROOM_NAMES[random]);
FILE *file = fopen(filePath, "ab+");
fprintf(file, "ROOM NAME: %s\n", ROOM_NAMES[random]); // Add room name
fclose(file);
rooms[i] = ROOM_NAMES[random];
connectionArr[random] = 1; // Room has been used
}
}
return rooms;
}
void * createConnections() {
for(i=0; i<7; i++) {
int connectionCount = rand() % 4 + 3; // Random number 3-6
int currentCount = 0;
for(j=0; j<7; j++) {
currentCount = currentCount + connections[i][j];
}
while (currentCount < connectionCount+1) {
int random = rand() % 7;
while (random == i) {
random = rand() % 7; // If random == current, reset random
}
// Set connections between both rooms
connections[i][random] = 1;
connections[random][i] = 1;
currentCount++;
}
}
}
void * connectionsToFiles() {
for(i=0; i<7; i++) {
int connectionCount = 1;
for(j=0; j<7; j++) {
if(connections[i][j] == 1) {
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[i]);
FILE *file = fopen(filePath, "ab+");
fprintf(file, "CONNECTION %d: %s\n", connectionCount, rooms[j]);
fclose(file);
connectionCount++;
}
}
}
}
void * roomTypesToFiles() {
for(i=0; i<7; i++) {
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[i]);
FILE *file = fopen(filePath, "a");
switch(i) {
case 0 :
fprintf(file, "ROOM TYPE: START_ROOM\n");
break;
case 6 :
fprintf(file, "ROOM TYPE: END_ROOM\n");
break;
default :
fprintf(file, "ROOM TYPE: MID_ROOM\n");
}
fclose(file);
}
}
isEndRoom(idx) {
movesRecord[totalMoves - 1] = rooms[idx];
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[idx]);
char roomType[20];
int lineNumber = 1;
FILE *file = fopen(filePath, "r");
int totaLines = 0;
char line[256];
while(fgets(line, sizeof line, file) != NULL) {
totaLines++; // Line count of room file
}
fclose(file);
file = fopen(filePath, "r");
while(fgets(line, sizeof line, file) != NULL) {
if(lineNumber == totaLines) {
int length = strlen(line) - 11;
strcpy(roomType, line+11);
roomType[length-1] = '\0';
}
lineNumber++;
}
// Check if this is the end room
if(strncmp(roomType, "END", 3) == 0) {
printf("YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!\n");
printf("YOU TOOK %d STEPS. YOUR PATH TO VICTORY WAS:\n", totalMoves - 1);
for(i=1; i<totalMoves; i++) {
printf("%s\n", movesRecord[i]);
}
return 1; // End was reached
} else {
return 0; // End was not reached
}
}
void * playGame(idx) {
totalMoves++;
printf("\n");
if(isEndRoom(idx)) {
exit(0);
}
while(1) {
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[idx]);
FILE *file = fopen(filePath, "r");
int totaLines = 0;
char line[100];
while(fgets(line, sizeof line, file) != NULL) {
totaLines++; // Line count of room file
}
fclose(file);
file = fopen(filePath, "r");
int lineNumber = 0;
char *roomChoices[6][20];
while(fgets(line, sizeof line, file) != NULL) { // Current room name
if(lineNumber == 0) {
char roomName[20];
int length = strlen(line) - 11;
strcpy(roomName, line+11);
roomName[length-1] = '\0';
printf("CURRENT LOCATION: %s\n", roomName);
}
else if(lineNumber == 1) { // First room choice option
printf("POSSIBLE CONNECTIONS: ");
fflush(stdout);
char roomName[20];
int length = strlen(line) - 14;
strcpy(roomName, line+14);
roomName[length-1] = '\0';
printf("%s", roomName);
strcpy(roomChoices[lineNumber - 1], roomName);
}
else if(lineNumber > 1 && lineNumber < totaLines - 1) { // Subsequent room choice options
printf(", ");
fflush(stdout);
char roomName[20];
int length = strlen(line) - 14;
strcpy(roomName, line+14);
roomName[length-1] = '\0';
printf("%s", roomName);
fflush(stdout);
strcpy(roomChoices[lineNumber - 1], roomName);
}
else {
printf(".");
fflush(stdout);
}
lineNumber++;
}
fclose(file);
printf("\nWHERE TO? >");
getRoomChoice(); // Get next room choice
if (strcmp(roomChoice, "time") == 0) {
pthread_t thread;
int rc = pthread_create(&thread, NULL, &getTime, NULL);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
pthread_mutex_lock(&mutex);
sleep(1);
FILE *file = fopen("currentTime.txt", "r");
char currentTime[25];
fgets(currentTime, sizeof currentTime, file);
printf("\n%s\n\n", currentTime);
pthread_mutex_unlock(&mutex);
} else {
for(i=0; i<totaLines-2; i++) {
if(strcmp(roomChoices[i], roomChoice) == 0) {
for(j=0; j<7; j++) {
if(strcmp(rooms[j], roomChoice) == 0) { // If the room is equal to roomChoice
playGame(j); // Make playGame call for new room
}
}
}
}
printf("\nHUH? I DON’T UNDERSTAND THAT ROOM. TRY AGAIN.\n\n");
fflush(stdout);
fflush(stdin);
}
}
}
int main() {
createRooms();
createConnections();
connectionsToFiles();
roomTypesToFiles();
playGame(0);
return 0;
}
1) Veröffentlichen Sie keine Bilder von Text! 2) 'fflush (stdin);' ruft undefiniertes Verhalten auf. 3) Wir sind kein Debugging-Service! Bei> 3k Wiederholungen sollten Sie [fragen] wissen und wie man ein [mcve] bereitstellt! – Olaf