Я пытаюсь написать легко отлаживать код. Есть ли лучший способ написать функцию do_save()
:
int one;
int two[10];
char three;
...
unsigned char *state = (unsigned char*)malloc(1024);
...
void do_save()
{
memcpy(state, &one, 4);
memcpy(state+4, two, 40);
memcpy(state+44, &three, 1);
}
Когда я говорю лучше, я имею в виду способ избежать создания ошибок, потому что я испортил подсчет размера, особенно когда в состоянии сохранено 10 или 20 переменных.
Используйте структуру.
int one;
int two[10];
char three;
typedef struct {
int one;
int two[10];
char three;
} State;
...
State *state = new State; // C++ish
State *state = malloc(sizeof(State)); //Cish
...
void do_save(State* state) {
state->one = &one;
memcpy(state->two, &two, sizeof(state->two));
state->three = three;
}
Есть много вещей, которые вы можете сделать легко, когда у вас есть структура. Например, вы можете сохранить свое текущее состояние и сохраненное состояние отдельно, а сохранение/восстановление может быть выполнено с помощью знака равенства. Запись в двоичный файл легко с fread/fwrite. Вы можете поместить свою структуру состояния в кучу или в стек, в зависимости от ваших потребностей.
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int one;
int two[10];
char three;
} State;
void print_state(State* state) {
printf("%i ", state->one);
int i;
for (i = 0; i < 10; ++i) {
printf("%i ", state->two[i]);
}
printf("%c\n", state->three);
}
int main() {
State* state = (State*)(malloc(sizeof(State)));
State current_state;
FILE* input = fopen("binary.data", "rb");
if (input) {
fread(¤t_state, sizeof(State), 1, input);
fclose(input);
}
print_state(¤t_state);
current_state.one = 1;
int i;
for (i = 0; i < 10; ++i) {
current_state.two[i] = i + 1;
}
current_state.three = 'Z';
*state = current_state;
FILE* output = fopen("binary.data", "wb");
fwrite(state, sizeof(State), 1, output);
fclose(output);
free(state);
}
memcpy
для всего этого
Вы можете использовать переменную для выполнения этой работы. Например:
int sizetotal = 0;
int sizethis = 0;
sizethis = sizeof(one);
memcpy(state+sizetotal, &one, sizethis);
sizetotal += sizethis;
sizethis = sizeof(*two);
memcpy(state+sizetotal, two, sizethis);
sizetotal += sizethis;
sizethis = sizeof(three);
memcpy(state+sizetotal, &three, sizethis);
sizetotal += sizethis;
Как вы можете видеть, три строки повторяются, поэтому их можно поместить в макро или функцию.
Конечно, если это C++, лучше всего было бы создать объект State и дать ему соответствующие методы.
sizethis = sizeof(*two);
Это дает 4 вместо желаемого размера, 40. Он пытается сохранить весь массив.
Использование C++:
int one;
std::array<int, 10> two;
char three;
std::vector<unsigned char> state(1024);
auto start = state.begin();
auto end = start + sizeof(one);
std::copy(start, end, &one);
start = ++end;
end += two.size();
std::copy(start, end, two.begin());
start = ++end;
end += sizeof(three);
std::copy(start, end, &three);
Похоже, вы копируете форму последовательных смещений из состояния буфера в некоторые другие местоположения. Вы можете копировать из последовательного смещения в последовательные смещения, просто используя Struct → следующим образом:
typedef struct {
int one;
int two[10];
char three;
} Container;
Container my_storage
...
unsigned char *state = (unsigned char*)malloc(1024);
...
void do_save(Container *dest, char*src) {
memcpy(src, state, sizeof(Container));
}
sizeof(int)
(илиsizeof(one)
) и умножение ... btwstd::unique_ptr<unsigned char[]> state = new unsigned char[1024];
может быть лучше