Thread: Array of pointers with addresses of words

  1. #1
    Registered User
    Join Date
    Oct 2020
    Posts
    69

    Array of pointers with addresses of words

    Task: Write a function that takes as parameter a string, an array of pointers and its length and fills the array with addresses to the beginning of each (whitespace-separated) word in the string (similar to the argv[] array of main). Terminate the array with a NULL pointer after the last valid address.
    I have some questions. 'An array of pointers' = array of addresses (correct me if I'm wrong I'm learning pointers). From what I know an address is a huge number, so how can I store the addresses of the words in the array, without overflowing it?
    Code:
    
    
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void wordAdresses(char *s, int *ptr_arr, int cap)
    {
        ptr_arr[0] = '\0';
        cap = 1;
        char* word = strtok(s, " ");
        while(word != NULL)
        {
            int address = *word;
            ptr_arr[cap] = *word;
            cap++;
            if(address+1 > cap)
            {
                printf("String overflow\n");
            }
            cap -= address;
            //printf("Word is %s <--> Value is %X\n",word, word);
            word = strtok(NULL, " ");
        }
        for(int i = 0; i < cap; i++)
        {
            printf("%d\n", ptr_arr[i]);
        }
    }
    int main()
    {
        char s[] = "john goes to school";
        int ptr_arr[100];
        wordAdresses(s, ptr_arr, sizeof ptr_arr);
        return 0;
    }

    Output:
    String overflow
    String overflow
    String overflow
    String overflow

    Now if I put the last for between comments and remove them for the second printf
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void wordAdresses(char *s, int *ptr_arr, int cap)
    {
        ptr_arr[0] = '\0'; 
        cap = 1;
        char* word = strtok(s, " ");
        while(word != NULL)
        {
            int address = *word;
            ptr_arr[cap] = *word;
            cap++;
            if(address+1 > cap)
            {
                printf("String overflow\n");
            }
            cap -= address;
            printf("Word is %s <--> Value is %X\n",word, word);
            word = strtok(NULL, " ");
        }
       /* for(int i = 0; i < cap; i++)
        {
            printf("%d\n", ptr_arr[i]);
        }*/
    }
    int main()
    {
        char s[] = "john goes to school";
        int ptr_arr[100];
        wordAdresses(s, ptr_arr, sizeof ptr_arr);
        return 0;
    }
    Output:
    String overflow
    Word is john <--> Value is 61FE00
    String overflow
    Word is goes <--> Value is 61FE05
    String overflow
    Word is to <--> Value is 61FE0A
    String overflow
    Word is school <--> Value is 61FE0D

    So I get the adress of the beginning of each word, but also the message "String overflow" because the numbers are huge. So how can I put the addresses into the array and avoid overflowing?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,302
    Quote Originally Posted by rmmstn
    fills the array with addresses to the beginning of each (whitespace-separated) word in the string
    That implies that the array of pointers is an array of char pointers (i.e., char*[N]), which means that the parameter should be a pointer to a pointer to char (i.e., char**).

    Quote Originally Posted by rmmstn
    From what I know an address is a huge number, so how can I store the addresses of the words in the array, without overflowing it?
    By using pointers. The value of a pointer is an address.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Is this correct?
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void wordAdresses(char *s, int *ptr_arr, int cap)
    {
        ptr_arr[0] = '\0';
        unsigned i, countWords = 0;
        char* word = strtok(s, " ");
        while(word != NULL)
        {
            cap = 1;
            for(i = 0; i < cap; i++)
            {
                *(ptr_arr+i) = word;
                printf("Word %s has address %X\n",word, *(ptr_arr+i));
            }
           // printf("Word is %s <--> Value is %X\n",word, word);
            word = strtok(NULL, " ");
            cap++;
        }
    }
    int main()
    {
        char s[] = "john goes to school";
        int ptr_arr[100];
        wordAdresses(s, ptr_arr, 100);
        return 0;
    }
    Output:
    Word john has address 61FE00
    Word goes has address 61FE05
    Word to has address 61FE0A
    Word school has address 61FE0D

    Now I would also need to watch for array overflow. What would be the condition for cap(cap < ? ), which if met, would overflow the array?

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4,003
    Sorry, I missed you are passing it in; still think that

    Code:
    ptr_arr[0] = '\0';
    defaults to an int array as in the K & R days.

    NOTE: It no longer does that.

    Tim S.
    Last edited by stahta01; 01-11-2021 at 01:51 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  5. #5
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Damn, yeah I treated it as an array of characters by mistake and I wanted to make sure that it is empty and null-terminated in the beginning. What would be the alternative to make sure my array isn't overflowing? Should I subtract from cap the size of a word in bytes to check if it overflows?

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    4,003
    Quote Originally Posted by rmmstn View Post
    Damn, yeah I treated it as an array of characters by mistake and I wanted to make sure that it is empty and null-terminated in the beginning. What would be the alternative to make sure my array isn't overflowing? Should I subtract from cap the size of a word in bytes to check if it overflows?
    It should be okay; unless you have a real old compiler!
    If you got a warning about shadowing you do have that problem.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,302
    Quote Originally Posted by rmmstn
    Is this correct?
    No, let's take a look at this line:
    Code:
    *(ptr_arr+i) = word;
    it would be slightly easier if we transformed it to use array notation:
    Code:
    ptr_arr[i] = word;
    ptr_arr[i] is an int, whereas word is a char*. You have a potential loss of information here because sizeof(int) >= sizeof(char*) is not guaranteed. In fact, it is quite possible that sizeof(int) == 4 whereas sizeof(char*) == 8.

    What I had in mind was something like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    void splitIntoWords(char *text, char **words, size_t cap)
    {
        size_t i = 0;
        char *word = strtok(text, " ");
        while (word && i < cap - 1)
        {
            words[i++] = word;
            word = strtok(NULL, " ");
        }
        words[i] = NULL;
    }
    
    int main(void)
    {
        char text[] = "john goes to school";
        char *words[100];
        splitIntoWords(text, words, sizeof(words) / sizeof(words[0]));
        for (size_t i = 0; i < sizeof(words) / sizeof(words[0]) && words[i]; ++i)
        {
            printf("%s @ %p\n", words[i], (void*)words[i]);
        }
        return 0;
    }
    Notice that as I mentioned in my previous post, the words parameter is a char** and the words local variable in main is an array of char pointers. This allows you to store the addresses of the words in the array.
    Last edited by laserlight; 01-11-2021 at 03:18 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Thanks a lot, it's so much clearer now! Just to make sure I understood fully, you wrote i < cap - 1 because we don't take the terminator '\0' into a account, right?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 05-26-2011, 06:44 AM
  2. Reversing Words and Array of Pointers
    By Striker87 in forum C Programming
    Replies: 3
    Last Post: 03-17-2011, 11:15 PM
  3. Addresses and pointers help...
    By GCNDoug in forum C Programming
    Replies: 13
    Last Post: 04-07-2007, 05:37 PM
  4. Pointers, addresses, and new
    By WarBaboon in forum C++ Programming
    Replies: 7
    Last Post: 06-06-2003, 10:12 PM
  5. Pointers and their Addresses
    By incognito in forum C++ Programming
    Replies: 6
    Last Post: 12-29-2001, 07:16 PM

Tags for this Thread