Ошибка сегментации кода C (дамп ядра)

Я попытался прокомментировать код и проверить, где он дает мне ошибку сегментации, но не смог ее найти. Я даже не могу установить отладчик gcc для проверки. Пожалуйста помоги!

#include<stdlib.h>
#include<string.h>
#include<stdio.h>

FILE *file;
char *registers[] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
char *regInBinary[] = {"000", "001", "010", "011", "100", "101", "110", "111"};
char delimiters[4] = " ,\n";
char binaryInstruction[17];

void convertToBinary(char *line);
void binaryToHex();

// Converting each line of source file into 16 bit binary
void convertToBinary(char *line){
    int count = 0;

    char *token = strtok(line, delimiters);
    while(token != NULL){
        // Opcodes
        if(strcmp(token, "add") == 0)
            strcpy(binaryInstruction, "0001");
        if(strcmp(token, "and") == 0)
            strcpy(binaryInstruction, "0101");
      //  if(strcmp(token, "halt") == 0)
      //      main();


        int i;
        for(i = 0; i < 8; i++){ // appends registers in binary
            if(strcmp(token, registers[i]) == 0){
                strcat(binaryInstruction, regInBinary[i]);
                count++;

                if(count == 2){
                    strcat(binaryInstruction, "000");
                }
             }
        }

        token = strtok(NULL, delimiters);
    }

}

// Converting 16 bit binary into hex
void binaryToHex(){
    char hex[5];
    int i, j;

    for(i = 0; i < 16; i = i + 0){
        for(j = 0; j < 4; j++){
            hex[j] = binaryInstruction[i];
            i++;
        }
        printf("%x", (int)strtol(hex, NULL, 2));
    }
    printf("\n");
}


// Starting program Part1
int main(int argc, char *argv[]) {
    char line[40];

    if(argc != 2)
        printf("Usage: %s source_file\n", argv[0]);
    else
        file = fopen(argv[1], "t1.asm"); // open source file

    while(fgets(line, sizeof(line), file)){
        convertToBinary(line);
        binaryToHex();
    }
    //printf("f025")
    fclose(file);
    return 0;
}

поэтому этот код отлично компилируется на моем терминале Mac с gcc, но выдает ошибку сегментации, когда я загружаю файл t1.asm.

Это программа на C для перевода инструкций языка ассемблера AND, ADD и HALT LC3 в машинный код.

Спасибо!


person JS Bae    schedule 23.10.2017    source источник
comment
Первая остановка — это ваш отладчик и просмотр вашего кода, чтобы найти ошибку. Если вы не можете установить отладчик (?), вы летите вслепую. Установите отладчик. Выясните, как, или вы будете в огромном невыгодном положении здесь. Помните: компиляция часто очень, очень далека от того, что я хочу.   -  person tadman    schedule 23.10.2017
comment
Здесь довольно много магических чисел, то есть чисел без объяснения их происхождения. Вы также довольно сильно полагаетесь на глобальные переменные, что является неустойчивой практикой. Переместите эти локальные функции в функции, которые в них нуждаются, пропустите их, если они требуются в другом месте.   -  person tadman    schedule 23.10.2017
comment
Деньги на char binaryInstruction[17]; слишком малы для того, что вы в них впихиваете, и ваша программа взрывается.   -  person tadman    schedule 23.10.2017
comment
for(i = 0; i < 16; i = i + 0){ .. технически это не проблема, так как вы увеличиваете i в теле цикла, но это странно. Измените его на цикл while или измените запоздалую/инкрементную часть на i=i+4.   -  person yano    schedule 23.10.2017
comment
сообщения об ошибках должны выводиться на stderr, а не stdout. например: это: printf("Usage: %s source_file\n", argv[0]); должно быть: fprintf( stderr, "Usage: %s source_file\n", argv[0]);   -  person user3629249    schedule 24.10.2017
comment
при вызове fopen() всегда проверяйте (!=NULL) возвращаемое значение, чтобы убедиться, что операция выполнена успешно.   -  person user3629249    schedule 24.10.2017
comment
относительно этих двух строк: int i; for(i = 0; i < 8; i++) данные должны храниться у пользователей этих данных. т.е. ограничить объем данных. Предложить: for( int i = 0; i < 8; i++)   -  person user3629249    schedule 24.10.2017
comment
в функции main(): когда количество параметров командной строки неверно, после вывода сообщения об ошибке следует вызвать exit(), НЕ продолжать выполнение программы. Аналогичные соображения существуют при проверке результатов вызова fopen() и т. д.   -  person user3629249    schedule 24.10.2017
comment
при написании прототипа функции, не принимающей параметров, поместите void между скобками. В противном случае компилятор сгенерирует код, принимающий любое число и любые параметры. Не то, что вы действительно хотите.   -  person user3629249    schedule 24.10.2017
comment
в функции: binaryToHex() локальный массив: hex[5]; имеет только первые 4 байта, т.е. пятый байт содержит мусор (какой бы мусор ни находился в стеке в этом месте. Функция: strtol() ожидает указатель на строку с завершением NUL. Настоятельно рекомендуется объявлять массив hex[] как: char hex[5] = {'\0'};   -  person user3629249    schedule 24.10.2017
comment
относительно: file = fopen(argv[1], "t1.asm"); 1) второй параметр - это "режим", а не какое-то имя файла. 2) проверьте (!=NULL) возвращаемое значение. предложить: FILE *file = fopen( argv[1], "r" ); if( NULL == file ) { perror( "fopen failed" ); exit( EXIT_FAILURE ); }   -  person user3629249    schedule 24.10.2017
comment
относительно: // if(strcmp(token, "halt") == 0) // main(); НИКОГДА не вызывайте main() рекурсивно, фактически, никогда не вызывайте main() из вашего кода   -  person user3629249    schedule 24.10.2017
comment
В качестве отступления: существует (обычно) пара сотен различных инструкций, И фактический объектный код может различаться в зависимости от операндов, И многие инструкции состоят из одного байта, И некоторые инструкции состоят из нескольких байтов. Итак, над функцией: convertToBinary() нужно много работать   -  person user3629249    schedule 24.10.2017
comment
относительно: for(i = 0; i < 16; i = i + 0) это неверно, так как индексная переменная i не изменяется. Кроме того, объем данных должен быть максимально ограничен. учитывая размещенный код, предложите: удалить оператор: int i, j; и заменить: for(i = 0; i < 16; i = i + 0) { for(j = 0; j < 4; j++) на: for( int i = 0; i < 16; i += 4 ) { for( int j=0; j < 4; j++ )   -  person user3629249    schedule 24.10.2017


Ответы (1)


file = fopen(arv[1], "t1.asm");

должно быть

file = fopen(argv[1], "r");

person qwn    schedule 23.10.2017