struct account{
char login[255];
char pass[255];
char name[255];
char category[255];
};
int accn=0;
account * pacc;
account * npacc;
char cin[255]; //ввод командной строки
void addacc(){
accn++;
pacc=(account*)realloc(pacc, sizeof(account)*accn);
npacc=pacc+sizeof(account)*(accn-1);
printf("Enter login: "); scanf("%s", &cin); memcpy(&(npacc->login), &cin, 255);
printf("Enter password: "); scanf("%s", &cin); memcpy(&(npacc->pass), &cin, 255);
printf("Enter name: "); scanf("%s", &cin); memcpy(&(npacc->name), &cin, 255);
printf("Enter category name: "); scanf("%s", &cin); memcpy(&(npacc->category), &cin, 255);
printf("Done!"); enter;
};
При первом вызове addacc()
все проходит успешно. При втором выдаёт ошибку после ввода логина.
В строке
npacc=pacc+sizeof(account)*(accn-1);
у вас работает арифметика указателей.
К примеру...
int A;
int *P = &A;
Предположим что переменная А находится по адресу 0. тогда сделав
P = P + 1;
мы получим адрес 4 так как переменная А занимает 4 байта.
А вы берете указатель на структуру и увеличиваете не на 1 что бы перейти к следующей структуре, а на размер структуры. а у неё размер больше 1024байт и поэтому вы в итоге обращаетесь к памяти которая находится на 1024 структуры дальше.
короче я наверно так хорошо вам не объясню, почитайте книжку по С или С++ про арефметику указателей и вам все станет ясно.
@ололо, а зачем Вы лишние операции &
пишите? Между прочим, компилятор будет ругаться (warning-ом). Да и выталкивать (fflush) вывод в приглашении и проверять ввод на конец файла не помешает.
Попробуйте что-то в духе
#define enter(prompt,field) (fputs((prompt), stdout), fflush(stdout), \
scanf("%s", (field)))
int addacc(){
pacc=(account*)realloc(pacc, sizeof(account) * ++accn);
npacc = pacc + accn - 1;
int rc = 1;
if (enter("Enter login: ", npacc->login) != 1 ||
enter("Enter password: ", npacc->pass) != 1 ||
enter("Enter name: ", npacc->name) != 1 ||
enter("Enter category name: ", npacc->category) != 1) {
--accn;
rc = 0;
}
return rc;
}
....
main () {
...
while (addacc())
printf ("account %d : %s %s %s %s\n", accn, pacc[accn-1].login, "", "", "");
...
}
В GNU есть нестандартное расширение, позволяющее "безопасно" читать scanf()-ом по формату %s (см.. man 3 fscanf). Используя его, макрос для ввода поля даннных с заданной максимальной длиной этого поля, можно переписать так (и лучше в виде статической функции)
static inline int enter(const char *prompt, char *field, int size)
{
char *buf; int rc;
fputs(prompt, stdout); fflush(stdout);
*field = 0;
if ((rc = scanf("%as", &buf)) == 1) {
strncat(field, buf, size);
free(buf);
} else
rc = 0;
return rc;
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Обновил задание на более прикладное: Необходимо выяснить, каков прогресс сериализации объектов классов(ну как полоска загрузки файла с сайта)
В итоге p1 и p2 будут указывать на один и тот же участок памятиПроизойдёт ли утечка памяти, занятой сначала p1
Есть модель POSTИ есть модель category_r В последней 3 столбца: id, Post_id, category_id