2017-02-10 5 views
-3

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; 
} 
+2

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

Antwort

0

Ich auch segfault und versuchte, den Code zu beheben. Jetzt lief es nach einigen Änderungen.

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <time.h> 
#include <pthread.h> 
#include <memory.h> 

struct stat st = {0}; 
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); 
    } 
} 

int isEndRoom(int 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(int 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; 
} 

-Test

rooms 

CURRENT LOCATION: Earth 
POSSIBLE CONNECTIONS: th, Air, Ice, DarkMatter, Earth, DarkMatter, Earth, Air, DarkMatter, DarkMatter, RT_ROOM. 
WHERE TO? >Air 

YOU HAVE FOUND THE END ROOM. CONGRATULATIONS! 
YOU TOOK 1 STEPS. YOUR PATH TO VICTORY WAS: 
Air 

Process finished with exit code 0 
Verwandte Themen