简体   繁体   English

HackerRank C 程序中的分段错误

[英]Segmentation fault in HackerRank C program

This is the challenge I'm trying to solve: https://www.hackerrank.com/challenges/querying-the-document/这是我要解决的挑战: https://www.hackerrank.com/challenges/querying-the-document/

So far I have made progress but I am stuck at a Segmentation Fault and I can't figure out why.到目前为止,我已经取得了进展,但我陷入了分段错误,我不知道为什么。 The following is an abridged version of the whole source code:以下是整个源代码的精简版:

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

char**** get_document(char* text) {

    int spaces = 0, periods = 0, newlines = 0; 
    for(int i = 0; i != strlen(text); i++) {
        if(text[i] == ' ')
            spaces++;
        else if(text[i] == '.')
            periods++;
        else if(text[i] == '\n')
            newlines++;
    }

    char** para[periods + 1]; // each paragraph stores that many sentences
    char* senten[spaces + 1]; // each sentence stores that many words
    char*** doc[newlines + 1]; // each document stores that many paragraphs

    int start = 0, k = 0, m, p = 0, x = 0;

    for(int i = 0; i != strlen(text); i++) {
        if(text[i] == ' ' || text[i] == '.') { // space or period means there was a word before it
            senten[k] = (char*) malloc(sizeof(char) * (i - start)); // store each word 
            m = 0;
            for(int j = start; j < i; )
                senten[k][m++] = text[j++];
            senten[k][m++] = '\0'; // append a '\0' to end the string

            if(text[i + 1] == '\n') { // newline means that a new paragraph is starting

                para[p] = senten; // store pointer to sentence in para
                while(k)
                    senten[k--] = NULL; // don't need now
                start = i + 2;
                p++;
            }
            else
                start = i + 1;
            k++;
        }
        if(i == strlen(text) - 1) { // end of file 
            doc[x++] = para; // store pointer to paragraph in doc
            while(p)
                para[p--] = NULL; // don't need
        }
    }
    return doc;
}

int main()
{
    char* text = "Hello World.\nHi.Bye.";
    char**** doc = get_document(text);
    printf("%s",doc[0][0][0]); // should print "Hello"
    return 0;
}

In short the program is supposed to take a char* and output a char**** .简而言之,该程序应该采用一个char*和 output 一个char****

Example:例子:

If char * text = "Hello World.\nHi.Bye."; if char * text = "Hello World.\nHi.Bye.";

Then char **** doc = {{{"Hello","World"}},{{"Hi"},{"Bye"}}};然后char **** doc = {{{"Hello","World"}},{{"Hi"},{"Bye"}}};

You return the local variable in get_document function:您在get_document function 中返回局部变量:

char** para[periods + 1]; // each paragraph stores that many sentences
char* senten[spaces + 1];
char*** doc[newlines + 1];
...
return doc;

It's bad idea, Because out of get_document function, the variable doc maybe does not exist.这是个坏主意,因为在get_document function 之外,变量doc可能不存在。

You should use:你应该使用:

char*** para = malloc((periods + 1) * sizeof(char **));
char** senten = malloc((spaces + 1) * sizeof(char *));
char**** doc = malloc((newlines + 1)*sizeof(char ***));

This is how I modified my code.这就是我修改代码的方式。 Now it passes all the test cases.现在它通过了所有的测试用例。

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


char**** get_document(char* newtext) {
    int spaces = 0, periods = 0, newlines = 0; 
    for(int i = 0; i != strlen(newtext); i++) {
        if(newtext[i] == ' ')
            spaces++;
        else if(newtext[i] == '.')
            periods++;
        else if(newtext[i] == '\n')
            newlines++;
    }

    char*** para = malloc((periods + 1) * sizeof(char **));
    char** senten = malloc((spaces + 1) * sizeof(char *));
    char**** doc = malloc((newlines + 1) * sizeof(char ***));

    int start = 0, k = 0, m, p = 0, x = 0, f = 0, pp = 0;
    int pcount = 0;
    for(int i = 0; i != strlen(newtext); i++) {
        if(newtext[i] == '.') pcount++;
        if(newtext[i] == ' ' || newtext[i] == '.') { // space or period means there was a word before it
            senten[k] = (char*) malloc(sizeof(char) * (i - start) + 1); // store each word 
            m = 0;

            for(int j = start; j < i; )
                senten[k][m++] = newtext[j++];

            senten[k][m++] = '\0'; // append a '\0' to end the string
            k++;

            if(i != strlen(newtext) && newtext[i + 1] == '\n') // newline means that a new paragraph is starting
                start = i + 2;
            else
                start = i + 1;

            if(i != strlen(newtext) && isalpha(newtext[i + 1]) && newtext[i] == '.') {
                para[p++] = senten;  
                senten = malloc((spaces + 1) * sizeof(char *));
                k = 0;

            }      

            if((i != strlen(newtext) && newtext[i + 1] == '\n') || i + 1 == strlen(newtext)) {
                para[p++] = senten;
                senten = malloc((spaces + 1) * sizeof(char *));
                k = 0;
                doc[f++] = &(para[pp]);
                pp += pcount;
                pcount = 0;
            }     
        } 
    }
    return doc;  
}

int main()
{
    char* newtext = "Hello World.\nHi.Bye.\nWow.";
    char**** doc = get_document(newtext);
    printf("%s\n", doc[0][0][0]);
    printf("%s\n", doc[0][0][1]);
    printf("%s\n", doc[1][0][0]);
    printf("%s\n", doc[1][1][0]);
    printf("%s\n", doc[2][0][0]);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM