2014-10-07 1 views
1

Итак, я тратил часы, пытаясь найти источник этой ошибки 11-й ошибки сегментации, и я надеялся, что вы, ребята, можете мне помочь.Я в затруднении с поиском segfault в своей программе

Таким образом, целью программы является найти перенаправление во входной строке и вернуть структуру redirCode, которая дает направление перенаправления, имя_файла и argsWithoutFile.

Пример ввода:

"ls -a > test.txt" 

возвращает код REDIR с:

argsWithoutFile = "ls -a" 
fileName = "test.txt" 
code = 2      //stdout 

Я уверен, что вина сегментный исходит от попыток сделать подстроки. Цикл for кажется прекрасным, потому что, когда я комментирую материал подстроки в конце, он не дает segfault. Мне все кажется прекрасным, кроме подстроки. В основном для подстроки Я хочу, чтобы это было так:

char *input = "ls -a > test.txt' 
char *desiredSubString = "ls -a " 

Вот код в полном объеме:

#include <stdio.h> 
#include <string.h> 
#define BUFFER  1024 
struct redirCode findRedirects(char *input); 
struct redirCode { 
    /* For code: 
    * 0 = none 
    * 1 = stdin 
    * 2 = stdout 
    */ 
    int code; 
    char *argsWithoutFile; 
    char *fileName; 
}; 

int main(){ 
    const char *delims = "<>"; 
    struct redirCode temp; 
    char line[BUFFER]; 

    printf("Input: "); 
    fgets(line, 1024, stdin); 
    temp = findRedirects(line); 

    printf("temp:\n"); 
    printf("temp.code = %d\n", temp.code); 
    printf("temp.fileName = %s\n", temp.fileName); 
    printf("temp.argsWithoutFile = %s\n", temp.argsWithoutFile); 

} 

/* Looks for '>', '<' in a string. 
* Will destroy string *input 
* Returns a redirCode struct with: 
* 1. fileName - the name of file that 
* wants to be redirected/stdin 
* 2. code - the direction of redirect 
* 3. args - the arguments w/o filename 
* */ 
struct redirCode findRedirects(char *input) 
{ 
    const char *delims = "<>"; 
    struct redirCode redirToReturn; 

    //Do an initial search for the delimeters 
    //before strtok destroys it. O(n) time. 
    int redirectOperatorReached = 0; 
    int count = 0; 

    int i; 
    for (i = 0; input[i] != 0; i++){ 
     if (input[i] == '<'){ 
      redirToReturn.code = 1; 
      redirectOperatorReached = 1; 
     } 
     else if (input[i] == '>'){ 
      redirToReturn.code = 2; 
      redirectOperatorReached = 1; 
     } 
     else { 
      redirToReturn.code = 0; 
     } 
     if (redirectOperatorReached != 1){ 
      count++; 
     } 
    } 
    printf("sizeof(input) = %lu\n", sizeof(input)); 
    printf("count = %d\n", count); 
    strncpy(redirToReturn.argsWithoutFile, input, count); 
    printf("input = %s\n", input); 
    redirToReturn.argsWithoutFile[count] = '\0'; 
    printf("argsW/oFile = %s\n", redirToReturn.argsWithoutFile); 

    return redirToReturn; 
} 

А вот некоторые терминальные журналы

MacBook-Air:practice keithy$ cc strtokOnlyOnce.c 
MacBook-Air:practice keithy$ ./a.out 
Input: hi 
sizeof(input) = 8 
count = 3 
Segmentation fault: 11 
MacBook-Air:practice keithy$ cc strtokOnlyOnce.c 
MacBook-Air:practice keithy$ ./a.out 
Input: ls -a > test.txt 
sizeof(input) = 8 
count = 6 
Segmentation fault: 11 
MacBook-Air:practice keithy$ 

EDIT: Я получил его на работу! Все, что мне нужно было сделать, это malloc строки в redirCode. Вот рабочий код:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define BUFFER  1024 
struct redirCode findRedirects(char *input); 
struct redirCode { 
    /* For code: 
    * 0 = none 
    * 1 = stdin 
    * 2 = stdout 
    */ 
    int code; 
    char *argsWithoutFile; 
    char *fileName; 
}; 

int main(){ 
    const char *delims = "<>"; 
    struct redirCode temp; 
    char line[BUFFER]; 

    printf("Input: "); 
    fgets(line, 1024, stdin); 
    temp = findRedirects(line); 

    printf("temp.code = %d\n", temp.code); 
    printf("temp.fileName = %s\n", temp.fileName); 
    printf("temp.argsWithoutFile = %s\n", temp.argsWithoutFile); 

} 

/* Looks for '>', '<' in a string. 
* Will destroy string *input 
* Returns a redirCode struct with: 
* 1. fileName - the name of file that 
* wants to be redirected/stdin 
* 2. code - the direction of redirect 
* 3. args - the arguments w/o filename 
* */ 
struct redirCode findRedirects(char *input) 
{ 
    const char *delims = "<>"; 
    struct redirCode *redirToReturn = malloc(sizeof(struct redirCode)); 

    //Do an initial search for the delimeters 
    //before strtok destroys it. O(n) time. 
    int redirectOperatorReached = 0; 
    int count = 0; 

    int i; 
    for (i = 0; input[i] != 0; i++){ 
     if (input[i] == '<'){ 
      redirToReturn->code = 1; 
      redirectOperatorReached = 1; 
      input[i] = ' '; 
     } 
     else if (input[i] == '>'){ 
      redirToReturn->code = 2; 
      redirectOperatorReached = 1; 
      input[i] = ' '; 
     } 
     if (redirectOperatorReached != 1){ 
      count++; 
     } 
    } 
    int lengthOfInput = strlen(input); 

    int sizeOfMalloc = (lengthOfInput+1)*sizeof(char); 
    redirToReturn->argsWithoutFile = (char *) malloc(sizeOfMalloc); 
    redirToReturn->fileName = (char *) malloc(sizeOfMalloc); 

    strncpy(redirToReturn->argsWithoutFile, input, count); 
    redirToReturn->argsWithoutFile[count] = '\0'; 

    strncpy(redirToReturn->fileName, input + count, lengthOfInput - count); 

    return *redirToReturn; 
} 

/*OUTPUT 
*./a.out 
*Input: ls -a > test.txt 
*temp.code = 2 
*temp.fileName = test.txt 
*temp.argsWithoutFile = ls -a 
*/ 
+6

Вы пробовали использовать отладчик? Если вы запустите отладчик с вашей программой, то он точно скажет вам, в какой момент в программе произошел segfault. – Frxstrem

+3

argsWithoutFile - NULL (ну, инициализируется случайным значением). Сначала вам нужно выделить буфер, и вы можете использовать его для strncpy. –

+1

Вы отлично поработали с отладкой printf, но вам нужно перейти к следующему шагу. Вывод идентифицирует 'strncpy (redirToReturn.argsWithoutFile, input, count);' как проблемную строку. Итак, копайте глубже там. Понимание того, что не так с этой конкретной программой, на самом деле не является большой проблемой. Это ваш шанс изучить некоторые навыки отладки, которые будут служить вам в течение остального времени. –

ответ

1
struct redirCode { 
     /* For code: 
     * 0 = none 
     * 1 = stdin 
     * 2 = stdout 
     */ 
     int code; 
     char *argsWithoutFile; 
     char *fileName; 
    }; 

Вам нужно выделить память для элемента структуры с именем char *argsWithoutFile; и char *fileName; перед его использованием.

Вы можете сделать так

struct redirCode *redirToReturn = malloc(sizeof(struct redirCode)); 
redirToReturn->argsWithoutFile = malloc(1024); 
redirToReturn->fileName = malloc(1024); 
1

1-> Вам нужно выделить память для argsWithoutFile с помощью new/malloc перед выполнением strncpy 2-> имени файла не инициализирован, и вы печатаете его в Printf. это неопределенное поведение.

Смежные вопросы