Обнаружение ошибки
Это утверждение в main
:
mal(argc, argv, &args);
говорит о необходимости передачи адреса от args
до mal
. Тип args
равен ARGS *
, поэтому тип &args
равен ARGS **
.
Это определение mal
:
int mal(int argc , char *argv[], ARGS *args)
говорит о том, что args
параметр имеет тип ARGS *
. Поскольку main
передает ARGS **
, а не ARGS *
, это ошибка.
Если вы используете ваш компилятор правильно, он должен был предупредить вас об одном из следующих вещей:
- В
main
объявление mal
не отображается. - В
main
вызов mal
не соответствует объявлению. - Определение
mal
не соответствует его объявлению.
Если компилятор не предупредил вас хотя бы об одном из них, то вам необходимо убедиться, что выполнены две вещи:
- Включите или увеличьте количество предупреждений в вашем компиляторе. Если вы используете GCC или Clang через командную строку, добавьте
-Wall
к ключам командной строки. Если вы используете другой интерфейс или другой компилятор, обратитесь к его документации. - Поместите объявление
mal
в заголовочный файл и используйте #include
, чтобы включить этот заголовочный файл в исходный файл, содержащий main
и исходный файл, содержащий mal
.
Размещение объявления в заголовочном файле и включение этого файла в каждый исходный файл является лучшим решением, чем копирование объявления в каждый исходный файл, поскольку он обеспечиваетИсходный файл использует ту же декларацию. И включение предупреждений компилятора - и обращая на них внимание - обеспечивает полную цепочку проверки типов - использование mal
в main
связано с его объявлением, а его объявление связано с его определением. Это позволяет компилятору выполнять всю проверку типов.
Исправление ошибки
Один из способов исправить ошибку - сделать так, чтобы определение mal
соответствовало тому, как вы его называете в main
,Для этого измените определение mal
, чтобы args
имел тип ARGS **
:
int mal(int argc , char *argv[], ARGS **args)
Затем внутри, mal
, так как тип args
изменился, вам нужноиспользовать *args
для ссылки на ARGS *
, который main
передал ему:
*args = malloc(sizeof (ARGS));
(*args)->IP_req = malloc(sizeof(char) * 200);
strcpy((*args)->IP_req,"12.21.51.88");
printf("arg IP:%s\n", (*args)->IP_req);
return 0;
Другие примечания
In main
, при печати строки с %s
, не передавайте адрес массива, как в printf("arg IP:%s\n", &args->IP_req);
. Передайте адрес первого элемента массива, используя printf("arg IP:%s\n", args->IP_req);
. (Хотя args->IP_req
изначально относится к массиву, в этом и большинстве контекстов он автоматически преобразуется в указатель на его первый элемент.)
В C (в отличие от C ++) вам не нужно приводитьрезультат malloc
, поэтому args->IP_req = (char*)malloc(sizeof(char) * 200);
может быть просто args->IP_req = malloc(sizeof(char) * 200);
.
При расчете размеров для перехода к malloc
лучше использовать sizeof
следующим образом:
*args = malloc(size **args);
args->IP_req = malloc(200 * sizeof *args->IP_req);
Таким образом, размер выделяемого объекта используется автоматически - если последующие изменения в коде изменяют тип, где объявляется args
или args->IP_req
, эти выражения автоматически используют новый размер. Необходимо изменить тип в двух или более местах (по одному в объявлении и по одному в каждом malloc
).