-1

text which i passed to get_document function is a normal string data.

1." " denotes separation of words.

2."." denotes separation of sentences.

3."\n" denotes separation of paragraphs.

get_document is a function which allocates each words, sentences, paragraphs for separate memory blocks making it easily accessible. Here's the code snippet.

char**** get_document(char* text) {
//get_document
int l=0,k=0,j=0,i=0;
char**** document = (char****)malloc(sizeof(char***));//para
document[l] = (char***)malloc(sizeof(char**));//sen
document[l][k] = (char**)malloc(sizeof(char*));//word
document[l][k][j] = (char*)malloc(sizeof(char));//letter

for(int z = 0; z < strlen(text); z++) {

    if(strcmp(&text[z]," ")==0) {
        document[l][k][j][i] = '\0';
        j++;
        document[l][k] = realloc(document[l][k],(sizeof(char*)) * j+1);
        i=0;
        document[l][k][j] = (char*)malloc(sizeof(char));
    }
    else if(strcmp(&text[z],".")==0) {
        k++;
        document[l] = realloc(document[l],(sizeof(char**)) * k+1);
        j=0;
        i=0;
        document[l][k] =(char**)malloc(sizeof(char*));
        document[l][k][j] = (char*)malloc(sizeof(char));
    }
    else if(strcmp(&text[z],"\n")==0) {
        l++;
        document = realloc(document,(sizeof(char***)) * l+1);
        k=0;
        j=0;
        i=0;
        document[l] = (char***)malloc(sizeof(char**));
        document[l][k] =(char**)malloc(sizeof(char*));
        document[l][k][j] = (char*)malloc(sizeof(char));

    }
    else {
        strcpy(&document[l][k][j][i],&text[z]);
        i++;
        document[l][k][j] = realloc(document[l][k][j],(sizeof(char)) * i+1);

    }

}
return document;

}

but when I run the program , I get the error

realloc:invalid next size

Can anyone help me with this. Thanks in advance.

adarshj
  • 31
  • 3
  • 5
    Word to the wise: if you find yourself going beyond two levels of indirection, *seriouisly* question whether you need to do whatever you think you're doing. And for all that is good in this world, [stop casting `malloc` in C programs](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). That said, your sample input and a driving `main` that invokes this and produces your error are relevant. Include them in your post to make a [mcve]. – WhozCraig Jan 14 '20 at 05:18
  • 2
    `char****` that is a huge design issue. – WedaPashi Jan 14 '20 at 05:50
  • Now I understand why most guys don't cast, Thanks @WhozCraig – adarshj Jan 14 '20 at 08:32
  • You might want to read about [correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – ad absurdum Jan 14 '20 at 14:48
  • regarding: `****` [read about 3 star programmer](https://wiki.c2.com/?ThreeStarProgrammer) – user3629249 Jan 16 '20 at 05:27

2 Answers2

1

when I run the program , I get the error

realloc:invalid next size

It appears that one of your realloc calls is failing because the allocator's tracking data has been corrupted. This is one of the more common things that can go wrong when you overwrite the bounds of an object, especially an allocated one. Which you do, a lot:

        strcpy(&document[l][k][j][i],&text[z]);

If you want to make any progress in your study of C, it is essential that you learn the difference between a char and a string. The C string functions, such as strcmp() and strcpy(), apply only to the latter. You may use them on empty strings (containing only a nul) or on single-character strings (containing one character plus a nul), among other kinds, but they are neither safe nor useful for individual chars. For individual chars you would use standard C operators instead, such as == and =.

In the case of the line quoted above, each strcpy call will attempt to copy the entire tail of the input string, including the terminator, into into the one-char-big space pointed to by &document[l][k][j][i]. This will always write past the end of the allocated space, often by a lot, thus producing undefined behavior. You appear to instead want:

        document[l][k][j][i] = text[z];

(well-deserved criticism of the choice of a quadruple pointer left aside). I see that you leave appending a string terminator for later, which is ok in principle, but I also see that you fail to terminate the last word of each sentence if the period ('.') immediately follows the word without any space.

Along the same lines, your several uses of strcmp() each compare the entire tail of the input string to one of several length-one string literals. Such comparisons are allowed, but they will not yield the results you appear to want. It appears you want simple equality tests against character constants, instead:

    if (text[z] == ' ')
    // ...
    else if (text[z] == '.')
    // ...
    else if (text[z] == '\n')

And of course, even with those corrections, your approach is highly inefficient. Memory [re]allocation is comparatively expensive, and you are performing an allocation or reallocation for every. single. character. in the document. At least scan ahead to the end of each word so as to allocate a word at a time, though it is possible to do better even than that.

Also, do not neglect the fact that malloc() and realloc() can fail, in which case they return a null pointer. Robust code is meticulous about checking for and handling error results from its function calls, including allocation errors.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

You mess up characters with strings.


You conditions to detect your elements are wrong:

if(strcmp(&text[z]," ")==0)
else if(strcmp(&text[z],".")==0)
...

Unless strlen(text) == 1 you will never enter any of your branches. strcmp compares strings, not single characters. This means it compares the whole remaining buffer with a string of length 1 which can never be true except for the last character. If you want to compare single characters, use if(text[z] == ' ') instead.


In your final else branch you completely smash your heap:

strcpy(&document[l][k][j][i],&text[z]);

You copy a string (again: the complete remaining buffer) into a single character. The memory for document[l][k][j] was allocated using size=1. This cannot even hold a string of length 1 because there is no room for terminating '\0' byte.

Copying the string into memory large enough to hold exactly 1 character, causes heap corruption and in any call to memory allocation function, this will finally explode as you can see with your error message.

What you need is:

document[l][k][j][i] = text[z];
document[l][k][j][i+1] = 0;

Finally your memory size for allocation is wrong:

document = realloc(document,(sizeof(char***)) * l+1);

You want to add 1 extra element to the array but you only add 1 byte. Use this instead:

document = realloc(document,(sizeof(char***)) * (l+1));

The same applies for all other levels of your construction.


In addition your naming of counters is poor. One character variable names should only be used for loops etc. where there is no risk of confusion. If you use them for different levels of array indexing, you should use names like wordcount, paracount etc. This would make the code much more readable.

Also I suggest you follow the hints in comments. Rethink your complete design.

Gerhardh
  • 11,688
  • 4
  • 17
  • 39