为什么我在重新分配时出现分段错误?

why am I getting Segmentation error while reallocing?

下面的代码是我解决黑客等级问题的一个片段- https://www.hackerrank.com/challenges/querying-the-document/problem

代码有效,但在调试期间, 当代码在“Learning C...”中达到 'C' 时,我在第 19,20 行收到分段错误并打印 NULLLLLL。我不明白为什么。

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

char ****get_document(char *text)
{
    int para = 0, sen = 0, word = 0, alph = 0;
    char c, ****doc = (char ****)calloc(1, sizeof(char ***));
    *doc = (char ***)calloc(1, sizeof(char **));
    **doc = (char **)calloc(1, sizeof(char *));
for (int i = 0; i < strlen(text); i++)
{
    c = text[i];

    if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
    {
        
        (*(*(*(doc + para) + sen) + word)) = (char *)realloc((*(*(*(doc + para) + sen) + word)), sizeof(char) * (alph + 1));
        if (((*(*(*(doc + para) + sen) + word))) == NULL)
            printf("NULLLLLLLLLLL"); // checking whether memory is given or not.
        (*(*(*(*(doc + para) + sen) + word) + alph)) = c;
        alph++;

    }
    else if (c == ' ')
    {
        *(*(*(doc + para) + sen) + word) = (char *)realloc((*(*(*(doc + para) + sen) + word)), sizeof(char) * (alph + 1));
        *(*(*(*(doc + para) + sen) + word) + alph) = '[=10=]';
        alph = 0;
        word++;
        *(*(doc + para) + sen) = (char **)realloc((*(*(doc + para) + sen)), sizeof(char *) * (word + 1)); // memory for word.
    }
    
}
return doc;
}



void main()
{
char text[] = "Learning C is fun.", ****d;
d = get_document(text);

}    

这一行

*(*(doc + para) + sen) = (char **)realloc((*(*(doc + para) + sen)), sizeof(char *) * (word + 1));

为句子中的下一个单词分配更多内存(pointer-to-char 或 char *)。它分配的内存包含一个不确定的指针值,因为 realloc 不会零初始化附加内存。

从输入字符串中的'C'开始,这一行

(*(*(*(doc + para) + sen) + word)) = (char *)realloc((*(*(*(doc + para) + sen) + word)), sizeof(char) * (alph + 1));

尝试使用不确定的指针值作为 realloc 的第一个参数。将之前未通过调用 malloccallocrealloc 或值 NULL 获得的任何指针值传递给 realloc,结果为 Undefined Behaviour.

客观地说,快速修复是

*(*(doc + para) + sen) = (char **)realloc((*(*(doc + para) + sen)), sizeof(char *) * (word + 1));
*(*(*(doc + para) + sen) + word) = NULL;

但这只会让你走到许多问题中的下一个:句子中的最后一个词永远不会是 null-terminated.

(主观上,这段代码连同这个根本上有缺陷的“挑战”应该被扔进垃圾箱。找一个经过良好审查的 C textbook,并正确地学习这门语言。)