Странное распределение памяти в случае указателей, использующих malloc - PullRequest
0 голосов
/ 28 июня 2018
#include <stdio.h>
#include <stdlib.h>

int main()
{
int *a = (int *)malloc(sizeof(int));
//    int a[1];
int i;
for(i = 0; i < 876; ++i)
    a[i] = i;
printf("%d",a[799]);
}

Почему этот код работает, даже если я выделяю только 1 int, используя malloc()?

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Почему этот код работает? Даже если я выделяю только 1 int, используя malloc? В таком случае ответ в неопределенном поведении.

Блок выделения 4 байтов, таких как

  int *a = (int *)malloc(sizeof(int)); /* No need to cast the malloc result  */

и доступ к этому как

a[i] = i; /* upto i<1 behavior is guaranteed as only 4byte allocated, not after */

приводит к неопределенному поведению Т.е. может случиться что угодно, и вы не должны зависеть от того, что он делает одно и то же дважды.

Примечание, приведение типа результата malloc() не требуется, поскольку malloc() тип возврата void* и его автоматическое преобразование безопасно в требуемый тип. Прочитайте Я разыгрываю результат malloc? И всегда проверяйте возвращаемое значение malloc(). например,

int *a = malloc(sizeof(int));
if( a != NULL) {
   /* allocated successfully & do_something()_with_malloced_memory() */ 
}
else {
    /* error handling.. malloc failed */ 
}
0 голосов
/ 29 июня 2018

Как объяснили другие, поведение при доступе к области памяти за пределами того, что выделено, не определено. Запустите ту же программу в системе, в которой работают приложения, интенсивно использующие память. Вы можете увидеть SIGSEGV. Запустите ваш код через статический анализ покрытия, и вы увидите, что он перехватывает переполнение буфера.

0 голосов
/ 28 июня 2018

Это , кажется, работает. Абсолютно ноль гарантирует, что он будет работать так же после перекомпиляции или в другой среде.

По сути, здесь вы пытаетесь получить доступ к адресу памяти, который не выделен вашей программе (используя любой индекс, кроме 0). Таким образом, с точки зрения вашей программы, адрес памяти равен неверно . Доступ к недопустимому расположению в памяти вызывает неопределенное поведение .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...