0

Update: Still none explained how to fix the problem with sizeof()

I wrote the following function in C99:

Explanation: the function gets an array of pointers with a length of size and fills it with words from the user input (World's length is >1 for sure).

Example of an input: Wish you great holiday

the code which is written inside Allocating Exact Size To The Extended Word block is to make my code a little more efficient and to allocate the exact size of memory for each world instead of assigning memory for the maximum string length.

The problem is that my code fails when testing it because of accessing a place of memory which I should not touch. can you help me fix that? The error is probably caused by one of the code lines inside the Allocating Exact Size To The Extended Word block.

#define WORDS_ARRAY_SIZE 100
#define MAX_STR_LEN 50

int read_words(char* words[], int size, int max_str_len)
{
    int i,j;
    bool Stop=false;
    for (i=0;i<size && !Stop;++i)
    {
        char tmp[1], ch, *word=tmp;
        for (j=0;j<max_str_len;++j)
        {
            if (scanf("%c",&ch)==EOF)
            {
                Stop=true;
                break;
            }
            if (ch==' ')
                break;
            word[j]=ch;
            //Allocating Exact Size To The Extended Word
            char* TmpExtendedword=malloc((i+2)*sizeof(char));
            if (TmpExtendedword==NULL)
            {
                free(TmpExtendedword);
                return -1;
            }
            strcpy(TmpExtendedword,word);
            word=malloc((i+2)*sizeof(char));
            if (word==NULL)
            {
                free(word);
                return -1;
            }
            strcpy(word,TmpExtendedword);
            //
        }
        word[j]='\0';
        words[i]=word;
    }
    return i;
}

int main()
{
    int num_words =0;
    char* words[WORDS_ARRAY_SIZE];
    num_words = read_words(words, WORDS_ARRAY_SIZE, MAX_STR_LEN);
}

Small note: how could I give the pointer word an initial size of 1 instead of pointing to an array which I will never use tmpword?

  • Would you be able to include a fully self-contained example that we can just compile and run, including a main function and an input file? Such an example is encouraged on Stack Overflow as it allows us to easily replicate your issue without making large guesses as to how your other code is implemented. – nanofarad Dec 26 '19 at 22:14
  • @ReinstateMonica-ζ-- I did that. Thanks for helping –  Dec 26 '19 at 22:18
  • 3
    `scanf` will never set `ch == EOF`. `scanf` returns EOF when it gets to the end of the file, it doesn't assign it to the parameter. – Barmar Dec 26 '19 at 22:18
  • 3
    `sizeof(word)` is the size of a pointer, not the length of the string that `word` points to. – Barmar Dec 26 '19 at 22:18
  • @Barmar If the input was a file (which is my case) then scanf() will receive and EOF at the end of it. what's wrong with that –  Dec 26 '19 at 22:20
  • `strcpy(TmpExtendedword,word)` on the first iteration is copying from `tmpword`, but it has never been initialized. – Barmar Dec 26 '19 at 22:20
  • 3
    You have to check the *return value* of `scanf()` for EOF, not the value of `ch`. – Barmar Dec 26 '19 at 22:20
  • regarding your second note I will try to add sizeof (*word) but are the rest uses of sizeof correct? (I am aiming to add a free space for one more char) –  Dec 26 '19 at 22:21
  • 5
    All your `sizeof` are wrong. You should use `strlen()` to get the length of a string. And add 1 for the null terminator. – Barmar Dec 26 '19 at 22:22
  • You could use `int ch = getc();` That will set `ch` to `EOF` when you get to the end of the file. – Barmar Dec 26 '19 at 22:25
  • There's no reason to use any function to get the length of the string. Just increment a counter variable in the loop. – Barmar Dec 26 '19 at 22:26
  • you told me to use sizeof(*word) but that's wrong, since in arrays for example we call sizeof with the pointer –  Dec 26 '19 at 22:30
  • 2
    @Daniel98 *you told me to use `sizeof(*word)`* No. He told you that `sizeof(word)` returns the size of the pointer and nothing more. Since `word` is a `char *` pointer, `sizeof( *word )` is the size of a `char`, which is one by definition. *since in arrays for example we call sizeof with the pointer* No, you do not. You call `sizeof()` with the array. An array is **NOT** a pointer. You need to be careful with what things are called - C doesn't allow any room for "freedom of interpretation". – Andrew Henle Dec 26 '19 at 22:34
  • (cont) Regarding arrays being pointers, see this: https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer I like to put it this way: pointers are variables that hold an address (that may not be valid!). Arrays are chunks of memory that HAVE an address. (And only the address of the array is passed to a function - so in the function it actually is only a pointer - a variable that holds an address) – Andrew Henle Dec 26 '19 at 22:36
  • Thanks, can someone take a look at the way I used sizeof() now? I have updated the code –  Dec 26 '19 at 22:38
  • still my code crashes –  Dec 26 '19 at 22:41
  • @AndrewHenle Please help me understand what is wrong? the code crashes and doesn't fill any words except the first one –  Dec 26 '19 at 22:47
  • Well, first thing you do in your loop is read a character into your `ch` variable, but you don't do anything with that character after you read it. It never winds up in `word`. – Andrew Henle Dec 26 '19 at 22:53

0 Answers0