Почему компилятор c не выдает ошибку, если я пытаюсь сохранить значения, превышающие значения, указанные во время динамического размещения? - PullRequest
0 голосов
/ 07 ноября 2019

Это то, что я пробовал. Я даже не заканчивал свою строку символом \0.

#include <stdio.h>
#include <malloc.h>
#include <string.h>

int main()
{
    int size=5;
    char *str = (char *)malloc((size)*sizeof(char));
    *(str+0) = 'a';
    *(str+1) = 'b';
    *(str+2) = 'c';
    *(str+3) = 'd';
    *(str+4) = 'e';
    *(str+5) = 'f';
    printf("%d    %s", (int)strlen(str), str);
    return 0;
}

Согласно правилу, он может хранить только 4 символа и один для \0, как я указал его в malloc. Это дает мне идеальный вывод.

Вывод

6    abcdef

Проверьте это здесь: https://onlinegdb.com/B1UeOXbjH

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Вы распределили свою собственную память, поэтому вы должны управлять ей ответственно. В вашем примере вы выделили 5 байт оперативной памяти и создали указатель, который указывает на первый адрес этой памяти. Ваш указатель не является строкой, это не массив. Итак, вы сделали 6 байтов, начиная с адреса, на который указывает указатель. 6-й байт переполняется в нераспределенной памяти. Итак, вы записали это в память, которая может быть использована для чего-то другого и может вызвать неизвестные проблемы. Вы создали утечку и не освободили память, выделенную при выходе из программы, что является еще одной утечкой. Вы нигде не добавили / 0, так что, честно говоря, вам повезло. На самом деле нет никакого способа узнать, как strlen () ответит. Если вы хотите, чтобы C обработал это для вас, тогда у вас есть char *str = "abcdef", и это создаст строку длиной 6 плюс / 0. Но если вы делаете это вручную, как вы, то вы должны справиться со всем.

0 голосов
/ 07 ноября 2019

C не считает свои массивы: если вы запрашиваете кусок памяти, состоящий из стольких байтов, он передает вам этот блок с помощью указателя, и вы можете управлять им ответственно.

Это приводит к некоторой эффективности - никаких накладных расходов, связанных с проверкой всего этого компилятором / средой выполнения, - но создает огромные проблемы для некорректного кода (пример которого вы показали).

Многим из нас очень нравитсяпрактическая эффективность C, но есть причина, по которой многие предпочитают такие языки, как Java или C #, которые управляют этим для вас и применяют границы массивов. Это компромисс.

...