所以当我在成功(没有警告/错误)编译后通过valgrind运行下面的代码时,我发现了一个错误,我不确定如何修复。有问题的代码来自this exercise,我不确定我输入的代码是错误的还是代码实际上已被破坏。
代码:
#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 :(得分:1)
@BLUEPIXY的意思是:
rc = read_scan("%c\n", MAX_DATA, &initial);
应该是这样的:
rc = read_scan("%c\n", &initial);