2015-04-12 45 views
0

因此,當我成功(無警告/錯誤)編譯後通過valgrind運行下面的代碼時,我發現一個錯誤,我不確定如何解決。有問題的代碼來自this exercise,我不確定是否輸入了錯誤的代碼或代碼是否被破壞。程序拋出Segmentation Fault 11,Valgrind發現錯誤

代碼

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
#include "../debugging/debug_macro.h" 

#define MAX_DATA 100 

int read_string(char **out_string, int max_buffer) { 

    *out_string = calloc(1, max_buffer + 1); 
    check_mem(*out_string); 

    char *result = fgets(*out_string, max_buffer, stdin); 
    check(result != NULL, "Input Error."); 

    return 0; 

error: 
    if(*out_string) free(*out_string); 
    *out_string = NULL; 
    return -1; 
} 

int read_int(int *out_int) { 
    char *input = NULL; 
    int rc = read_string(&input, MAX_DATA); 
    check(rc == 0, "Failed to read number"); 

    *out_int = atoi(input); 

    free(input); 
    return 0; 

error: 
    if(input) free(input); 
    return -1; 
} 

// Vaeriable Argument ... 
int read_scan(const char*fmt, ...) { 

    int rc = 0; 
    int *out_int = NULL; 
    char *out_char = NULL; 
    char **out_string = NULL; 

    int max_buffer = 0; 

    va_list argp; 
    va_start(argp, fmt); 

    for(int i = 0; fmt[i] != '\0'; i++) { 
     if(fmt[i] == '%') { 
      i++; 
      switch(fmt[i]) { 
       case '\0': 
        sentinel("Invalid format. You ended with %%."); 
        break; 
       case 'd': 
        out_int = va_arg(argp, int *); 
        rc = read_int(out_int); 
        check(rc == 0, "Failed to read int"); 
        break; 
       case 'c': 
        out_char = va_arg(argp, char *); 
        *out_char = fgetc(stdin); 
        break; 
       case 's': 
        max_buffer = va_arg(argp, int); 
        out_string = va_arg(argp, char **); 
        rc = read_string(out_string, max_buffer); 
        check(rc == 0, "Failed to read string."); 
        break; 

       default: 
        sentinel("Invalid format."); 
      } 
     } else { 
      fgetc(stdin); 
     } 

     check(!feof(stdin) && !ferror(stdin), "Input error."); 
    } 

    va_end(argp); 
    return 0; 

error: 
    va_end(argp); 
    return -1; 
} 

int main(int argc, char *argv[]) 
{ 
    char *first_name = NULL; 
    char initial = ' '; 
    char *last_name = NULL; 
    int age = 0; 
    int rc = 0; 

    printf("Enter First Name: "); 
    rc = read_scan("%s", MAX_DATA, &first_name); 
    check(rc == 0, "Failed first name."); 

    printf("Enter Initial: "); 
    rc = read_scan("%c\n", MAX_DATA, &initial); 
    check(rc == 0, "Failed initial."); 

    printf("Enter Last Name: "); 
    rc = read_scan("%s", MAX_DATA, &last_name); 
    check(rc == 0, "Failed last name."); 

    printf("Enter Age: "); 
    rc = read_scan("%d", &age); 

    printf("------ [ Results ] ------\n"); 
    printf("Fist Name: %s.", first_name); 
    printf("Initial: %c\n.", initial); 
    printf("Last Name: %s.", last_name); 
    printf("Age: %d\n.", age); 

    free(first_name); 
    free(last_name); 
    return 0; 

error: 
    return -1; 
} 

輸出

$ valgrind input_output/variable_input_output_functions 
==14933== Memcheck, a memory error detector 
==14933== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==14933== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info 
==14933== Command: input_output/variable_input_output_functions 
==14933== 
Enter First Name: Adam 
Enter Initial: K 
==14933== Invalid write of size 1 
==14933== at 0x100001569: read_scan (variable_input_output_functions.c:66) 
==14933== by 0x1000019F4: main (variable_input_output_functions.c:106) 
==14933== Address 0x64 is not stack'd, malloc'd or (recently) free'd 
==14933== 
==14933== 
==14933== Process terminating with default action of signal 11 (SIGSEGV) 
==14933== Access not within mapped region at address 0x64 
==14933== at 0x100001569: read_scan (variable_input_output_functions.c:66) 
==14933== by 0x1000019F4: main (variable_input_output_functions.c:106) 
==14933== If you believe this happened as a result of a stack 
==14933== overflow in your program's main thread (unlikely but 
==14933== possible), you can try to increase the size of the 
==14933== main thread stack using the --main-stacksize= flag. 
==14933== The main thread stack size used in this run was 8388608. 
==14933== 
==14933== HEAP SUMMARY: 
==14933==  in use at exit: 43,217 bytes in 429 blocks 
==14933== total heap usage: 505 allocs, 76 frees, 49,241 bytes allocated 
==14933== 
==14933== LEAK SUMMARY: 
==14933== definitely lost: 0 bytes in 0 blocks 
==14933== indirectly lost: 0 bytes in 0 blocks 
==14933==  possibly lost: 0 bytes in 0 blocks 
==14933== still reachable: 8,293 bytes in 3 blocks 
==14933==   suppressed: 34,924 bytes in 426 blocks 
==14933== Rerun with --leak-check=full to see details of leaked memory 
==14933== 
==14933== For counts of detected and suppressed errors, rerun with: -v 
==14933== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 
Segmentation fault: 11 

有人能告訴我怎麼回事?我知道錯誤在哪裏,我只是不知道錯誤的原因。我是新來的C.

+0

'RC = read_scan( 「%C \ n」,MAX_DATA,與初始);''case'c': out_char = va_arg(argp,char *); * out_char = fgetc(stdin);' – BLUEPIXY

+0

對不起,我不關注,你可以擴展一下嗎? – TheWebs

+0

調用者端具有大小參數'MAX_DATA',但'read_scan'被忽略。所以它正在處理和誤解參數。 – BLUEPIXY

回答

1

什麼@BLUEPIXY的意思是,這樣的:

rc = read_scan("%c\n", MAX_DATA, &initial); 

應該是這樣的:

rc = read_scan("%c\n", &initial); 
相關問題