2013-04-05 2 views
0

Я пробовал кусок кода, который делал переполнение массива, но произошло что-то неожиданное, когда я скомпилировал его с помощью gcc. Ниже приведен код:Что было сделано gcc, когда я пытаюсь сделать переполнение массива?

#include <stdio.h> 

int main(int argc, const char *argv[]) 
{ 
    int a[] = {0,2,4,7}; 
    int size = sizeof(a)/sizeof(int); 
    int i; 
    printf("%d, %X\n", size, &a); 
    a[4] = 6; 
    printf("%d, %X\n", size, &a); 
    a[5] = 78; 
    printf("%d, %X\n", size, &a); 
    a[6] = 65; 
    printf("%d, %X\n", size, &a); 
    for (i = 0; i < size; i++) { 
     printf("%d, ", a[i]); 
    } 
    printf("%d, %d, %d\n", a[size], a[size+1], a[size+2]); 
    printf("\n"); 
    return 0; 
} 

и результат:

4, BFC4DDF8 
6, BFC4DDF8 
6, BFC4DDF8 
6, BFC4DDF8 
0, 2, 4, 7, 6, 5, 65, 0, 0 

Так в коде, я не изменил значение размера, но когда он бежал, это было изменение само по себе! Так может кто-нибудь сказать мне, почему это происходит?

PS: gcc версия 4.8.0.

В соответствии с ответом @NPE, и я проверяю адрес size, и он фактически находится в памяти сразу после a.

Но когда я добавить кусок кода

printf("%X\n", &size); 

перед тем

printf("%d, %X\n", size, &a); 

результат

BFC39108 
4, BFC3910C 
4, BFC3910C 
4, BFC3910C 
4, BFC3910C 
0, 2, 4, 7, 4, 78, 65 

в это время, size находится в памяти непосредственно перед a.


В самом деле, где бы я печатаю size 's адрес, он расположен прямо перед a' s адрес; и если я не печатаю адрес size, он находится сразу после адреса a. Это все еще неопределенное поведение компилятора?

+0

Я ожидал, что значение размера не должно изменяться. – Jude

+1

Вы больше не можете ожидать, что когда у вас будет неопределенное поведение. – NPE

ответ

4

Поскольку вы пишите в конце a, ваша программа имеет undefined behaviour. Это означает, что он может вести себя так, как это угодно, в том числе в том, как вы наблюдаете.

То, что происходит на практике, что size случается находиться в памяти сразу после a, и следующий недоступного задания:

a[4] = 6; 

перезаписывает size.

Обратите внимание, что код может потерпеть неудачу каким-либо другим способом, если вы используете другой компилятор или разные настройки компилятора или делаете, по-видимому, несущественные изменения в программе. Или он может хорошо работать на протяжении всего тестирования, а затем взорваться на лице вашего клиента.

+0

Но кажется, что 'size' находится в memeory сразу после' a' каждый раз, когда он запускается. – Jude

+0

@ Jude: Компьютеры достаточно предсказуемы в том случае, если вы дадите им одни и те же инструкции, они будут делать то же самое. Поэтому вы не должны удивляться. Поведение все еще не определено, и завтра 'размер' может быть не найден сразу после' a'. – NPE

+0

Я только что отредактировал этот вопрос, и если я напечатаю адрес 'size' в любом месте, он просто расположен прямо перед адресом' a'. Так это пасхальное яйцо все еще компилятора? – Jude

0

Вы перезаписали память за концом массива [] и поэтому перезаписали значение размера.

Смежные вопросы