В настоящее время я использую книгу, чтобы немного научиться сборке. Часть книги, в которой я работаю, посвящена malloc и бесплатности. Чтобы лучше понять это, в книге представлен ассемблерный код, создающий простую и бесплатную реализацию malloc, которая затем используется другой небольшой программой на языке C:
#include<stdio.h>
void *allocate(int);
void deallocate(void *);
int main() {
char *a1 = allocate(500);
char *a2 = allocate(1000);
char *a3 = allocate(100);
fprintf(stdout, "Allocations: %d, %d, %d\n", a1, a2, a3);
deallocate(a1);
char *a4 = allocate(1000);
char *a5 = allocate(250);
char *a6 = allocate(250);
fprintf(stdout, "Allocations: %d, %d, %d, %d, %d, %d\n", a1, a2, a3, a4, a5, a6);
fscanf(stdin, "%s", a5);
fprintf(stdout, "%s\n", a5);
}
Я получаю ассемблерный код, но после их компиляции в терминале Linux с помощью:
gcc -static allocate.s usealloc.c -o usealloc
Я получаю несколько таких ошибок:
usealloc.c:12:40: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘char *’ [-Wformat=]
12 | fprintf(stdout, "Allocations: %d, %d, %d\n", a1, a2, a3);
| ~^ ~~
| | |
| int char *
| %s
Я предполагаю, что %d ожидает аргумент int, который противоречит объявлению a1, a2 и a3 char. Я еще не совсем знаком с C, но решил, что в опубликованной книге не будет такой простой проблемы, поэтому любая помощь приветствуется!
Я рекомендую вам сначала изучить C, прежде чем изучать ассемблер. Или, по крайней мере, не пытайтесь изучать и то, и другое одновременно. Выберите один и сначала изучите его как следует, затем другой, прежде чем пытаться их смешать.
Re: «Я полагал, что в опубликованной книге не будет такой простой проблемы»: это неправильный расчет. Изданные книги имеют ошибки.
@n.m.couldbeanAI До этого момента с книгой все было в порядке. Это было легко понять. В любом случае, я считаю, это хороший урок.
@Someprogrammerdude Спасибо за совет. Согласен, глупо было бы изучать и то, и другое одновременно. Книга продается как пособие для начинающих. C будет моим следующим языком, который я выучу.
Если книга старая, возможно, она была написана в те времена, когда int
и указатели были обычным размером. В то время компиляторы еще не научились проверять строки формата.
Во-первых, здорово, что вы обращаете внимание на предупреждения! Жаль, что авторы книги этого не сделали.
Вы можете убрать это предупреждение, если явно приведете эти указатели на символы к int
:
fprintf(stdout, "Allocations: %d, %d, %d, %d, %d, %d\n", (int) a1, (int) a2, (int) a3, (int) a4, (int) a5, (int) a6);
А еще лучше вместо этого использовать %p
, который используется для печати красиво отформатированных указателей, таких как 0x600000de0000
:
fprintf(stdout, "Allocations: %p, %p, %p, %p, %p, %p\n", a1, a2, a3, a4, a5, a6);
%p
указано, чтобы принимать аргумент типа void *
, а не char *
. Некоторые компиляторы предупреждают об этом. Таким образом, аргументы, которые будут напечатаны с %p
, должны быть приведены к void *
.
Приятно знать. Кланг не жаловался, но да, ОП может (void *)
если нужно
Спасибо вам обоим! Это скомпилировано без ошибок после того, как я попробовал оба решения, но я буду иметь это в виду.
Возможно, вам не следует использовать эту книгу. "в опубликованной книге не было бы такой простой проблемы" у меня для вас плохие новости...