C程序在本地运行正常,但在远程服务器上运行段错误

时间:2017-02-10 20:15:07

标签: c segmentation-fault remote-server

我有一个我写的命令行游戏,可以在本地运行,但在远程服务器上运行段错误。我还没有找到原因。

本地:

远程:

在某些地方显然存在聚集/显示可能连接的问题。

这是完整的计划。这个问题可能发生在第190行附近,就像可能的连接逻辑所在的那样。我觉得我的strncpy行存在问题,因为那里有非常具体的内存操作,但我可能错了。

#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 个答案:

答案 0 :(得分:0)

我也遇到了段错并试图修复代码。现在它确实在一些变化之后运行。

#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;
}

测试

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