Почему у меня обнаружен разрыв стека?
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char currency[80];
double exchangerate;
} exchangeT;
void main()
{
char from[10];
int i;
printf("convert from: ");
scanf("%s", &from[10]); //this seems to be where the problem is
//printf("into: ");
//scanf("%s", to);
//printf("How many of type %s", to);
FILE *file = fopen("/home/jeffwang/Desktop/exchange.dat", "r");
exchangeT exchange[5];
for(i = 0; i < 5; i++)
{
fscanf(file, "%s %lf", &exchange[i].currency, &exchange[i].exchangerate);
printf("%s %lf\n", exchange[i].currency, exchange[i].exchangerate);
//if(strcmp (from[8], exchange[0].currency) == 0)
// printf("lel\n");
}
}
это фактическое сообщение об ошибке
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7700eb5]
/lib/i386-linux-gnu/libc.so.6(+0x104e6a)[0xb7700e6a]
./a.out[0x8048622]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb76154d3]
./a.out[0x8048471]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 667062 /home/jeffwang/Desktop/ECS 30/a.out
08049000-0804a000 r--p 00000000 08:01 667062 /home/jeffwang/Desktop/ECS 30/a.out
0804a000-0804b000 rw-p 00001000 08:01 667062 /home/jeffwang/Desktop/ECS 30/a.out
09d8e000-09daf000 rw-p 00000000 00:00 0 [heap]
b75cd000-b75e9000 r-xp 00000000 08:01 918526 /lib/i386-linux-gnu/libgcc_s.so.1
b75e9000-b75ea000 r--p 0001b000 08:01 918526 /lib/i386-linux-gnu/libgcc_s.so.1
b75ea000-b75eb000 rw-p 0001c000 08:01 918526 /lib/i386-linux-gnu/libgcc_s.so.1
b75fb000-b75fc000 rw-p 00000000 00:00 0
b75fc000-b77a0000 r-xp 00000000 08:01 918505 /lib/i386-linux-gnu/libc-2.15.so
b77a0000-b77a2000 r--p 001a4000 08:01 918505 /lib/i386-linux-gnu/libc-2.15.so
b77a2000-b77a3000 rw-p 001a6000 08:01 918505 /lib/i386-linux-gnu/libc-2.15.so
b77a3000-b77a6000 rw-p 00000000 00:00 0
b77b2000-b77b8000 rw-p 00000000 00:00 0
b77b8000-b77b9000 r-xp 00000000 00:00 0 [vdso]
b77b9000-b77d9000 r-xp 00000000 08:01 918485 /lib/i386-linux-gnu/ld-2.15.so
b77d9000-b77da000 r--p 0001f000 08:01 918485 /lib/i386-linux-gnu/ld-2.15.so
b77da000-b77db000 rw-p 00020000 08:01 918485 /lib/i386-linux-gnu/ld-2.15.so
bfd29000-bfd4a000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
Чего я не понимаю: я использую пользовательский ввод из [10] и никогда не превышаю 10. Кроме того, если я удаляю указатель & в scanf, сообщение об ошибке не появляется. Кроме того, когда я изменяю с [10] на что-то меньшее, скажем, из [2], ошибка также не возникает! Wut?!
1 ответ
Решение
Да, это определенно неправильно.
char from[10];
scanf("%s", &from[10]);
Выражение &from[10]
это адрес конца массива. Не последний элемент, но элемент "мимо" последнего элемента, несуществующий элемент. Используйте это вместо:
scanf("%s", from); // Still wrong
Обратите внимание, что это тоже плохо, потому что вы можете получить более 10 символов from
,
scanf("%10s", from); // Correct