Как использовать calloc() в C?

Разве я не должен получить ошибку, если моя строка в этой программе превышает 9 символов?

// CString.c
// 2.22.11

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

main()
{
    char *aString = calloc(10, sizeof(char));

    if (aString == NULL)
    {
        return 1;
    }

    printf("PLEASE ENTER A WORD: ");
    scanf("%s", aString);

    printf("YOU TYPED IN: %s\n", aString);
    //printf("STRING LENGTH: %i\n", strlen(aString));
}

Спасибо

вор


person nambvarun    schedule 24.02.2011    source источник
comment
то, что вы передаете, scanf является указателем ... и время выполнения c не содержит никакой информации о размере выделенного указателя ... ну, он может содержать эти данные ... но он недоступен для стандартных программ C ... вы можете быть в состоянии использовать функции интроспекции кучи для получения доступного размера)   -  person vrdhn    schedule 24.02.2011


Ответы (2)


Вы не получите ошибку компилятора, потому что синтаксис правильный. Что неверно, так это логика, и вы получаете неопределенное поведение, потому что вы записываете в память после конца буфера.

Почему это поведение undefined? Ну, вы не выделили эту память, что означает, что она вам не принадлежит — вы вторгаетесь в область, которая закрыта предупредительной лентой. Подумайте, использует ли ваша программа память сразу после буфера. Теперь вы перезаписали эту память, потому что вы переполнили свой буфер.

Рассмотрите возможность использования спецификатора размера следующим образом:

scanf("%9s", aString);

так что вы не переполняете свой буфер.

person Marlon    schedule 24.02.2011
comment
@blargman: Неопределенное поведение означает что угодно может произойти. Это включает в себя разрешение вашей программе работать. Это также включает в себя сбой вашего компьютера, взрыв вашего мобильного телефона, остановку вращения Земли и возвращение Гитлера к жизни. Другими словами, неопределенное поведение означает, что нет никакой гарантии, что это будет работать так, как вы хотите. Вы не можете полагаться на неопределенное поведение, чтобы постоянно обеспечивать ожидаемое поведение. - person In silico; 24.02.2011
comment
@blaragman: Нет никаких гарантий относительно того, что будет делать ваша программа. Что происходит сейчас, так это то, что вы пишете в память, которую вы не выделили должным образом. Может случиться что угодно, от идеальной работы до сбоя программы. - person Nicholas Knight; 24.02.2011
comment
Итак, это случай переполнения буфера? - person nambvarun; 24.02.2011
comment
@Р..: Точно. UB означает, что всё может случиться. (Я надеялся, что кто-то поймал это.) :-) - person In silico; 24.02.2011
comment
Также обратите внимание, что использование таких инструментов, как Valgrind или Purify, может помочь обнаружить этот тип ошибок. - person Raph Levien; 24.02.2011
comment
@blargman Да, именно, это пример переполнения буфера. C - это древний и примитивный язык, который не поддерживает и, следовательно, не проверяет длину массивов... если вы пишете дальше конца, данные перезаписывают что-то... другие переменные, код, тут ничего не скажешь. Если вы обнаружите, что что-то настолько небезопасное, что вызывает беспокойство, подумайте об использовании более современного языка. - person Jim Balter; 24.02.2011

Да, у тебя ошибка. И самое обидное, что вы об этом не знаете. Вы можете узнать об этом позже в программе, когда что-то таинственным образом выйдет из строя (если вам повезет), или когда адвокаты вашего клиента придут судиться с вами (если вам не повезет).

person R.. GitHub STOP HELPING ICE    schedule 24.02.2011