Что такое UndefinedBehaviorSanitizer в контексте моего кода - PullRequest
0 голосов
/ 17 января 2019

Я пытался завершить крэк с pset2 в cs50, и когда я компилировал свой код, он не выдавал никаких ошибок, но когда я запустил свой код, он выдал какую-то ошибку.

Я попытался удалить разные части моего кода и обнаружил, что после устранения всех циклов for ошибка перестает отображаться

int main(int argc, string argv[])
{
    if (argc == 2)
    {
        printf("%s", crypt(argv[1], "hi"));
        string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", mess[1];
        int sl = strlen(letters);
        for (int x = 0; x < sl; x++)
        {
            mess[0][0] = letters[x];
            for (int y = 0; y < sl; y++)
            {
                mess[0][1] = letters[y];
                for (int z = 0; z < sl; z++)
                {
                    mess[0][2] = letters[z];
                    for (int a = 0; a < sl; a++)
                    {
                        mess[0][3] = letters[a];
                        for (int b = 0; b < sl; b++)
                        {
                            mess[0][4] = letters[b];
                            printf("%s", mess[0]);
                        }
                    }
                }
            }
        }
    }
    else
    {
        return 1;
    }
}

Я ожидал перебрать каждую возможную комбинацию из 5 буквенных комбинаций и вывести строку из этих 5 букв. вместо этого он возвращает это:

UndefinedBehaviorSanitizer:DEADLYSIGNAL
==665==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000402a60 (pc 0x000000428037 bp 0x7ffd0ab11070 sp 0x7ffd0ab10e60 T665)
==665==The signal is caused by a WRITE memory access.
    #0 0x428036 in main /root/sandbox/test.c:16:24
    #1 0x7f16d0022b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #2 0x402a89 in _start (/root/sandbox/test+0x402a89)

UndefinedBehaviorSanitizer can not provide additional info.
==665==ABORTING

Я хочу знать, что означает эта ошибка, почему она возникает и как я могу избежать ее в будущем

Ответы [ 2 ]

0 голосов
/ 17 января 2019

В cs50 string - это typedef для char *. mess[0] имеет тип char *, но никогда не инициализировался. Вам либо нужно выделить место с malloc

mess[0] = malloc(somesize * sizeof *mess[0]);

или вы можете использовать массив char:

char mess[1][somesize];

Также обратите внимание, что если вы хотите напечатать mess с printf("%s", mess[0]);, он должен заканчиваться NUL.

0 голосов
/ 17 января 2019

string mess[1];

string от cs50 обозначается как char * от здесь .

Так что оно равно:

char *mess[1];

Это неинициализированный массив из одного элемента. Тип элементов - указатель на символ.

mess[0][0] = ...

Это берет неинициализированный указатель mess[0], разыменовывает его и присваивает ему. mess[0] неинициализирован, поэтому это недопустимый указатель, присвоение mess[0][0] недопустимо - там нет действительной памяти. Там нет памяти для записи.

Вы можете выделить память, т. Е.

mess[0] = malloc(256 * sizeof(char));

т. выделит память для 256 символов (если успешно) и вернет указатель на эту область памяти. Указатель хранится в первом члене массива mess. Тогда mess[0] будет указывать на некоторую область памяти, которая выделена только для вашей программы и действительна для 256 символов.

...