Search code examples
arrayscpointersstructpointer-to-pointer

Getting Null iterate through to next element of array using pointers


#import<stdio.h>
#import<stdlib.h>

typedef struct Video {
    char *name;
    int unique_views;
} Video;

typedef struct Viewer {
    char *username;
    Video *watched_videos;
    int watched_videos_size;
} Viewer;

int count_views(Viewer **viewers, int viewers_size, char *video_name)
{
    Viewer *ptr;
    Video *vid;
    int count=0;
    ptr = *viewers;
    for (int i=0;i< viewers_size;i++){
        printf("%s ",ptr->username);
        vid=ptr->watched_videos;
        for (int j=0;j < ptr->watched_videos_size;j++){
            printf("%d %d",j,ptr->watched_videos_size);
            printf("%s \n",vid->name);
            if (vid->name == video_name){
                count++; 
            }
            vid++;
        }
        ptr++;
    }
    return count;
}

int main()
{
    Video videos[] = { {.name = "Soccer", .unique_views = 500},
                       {.name = "Basketball", .unique_views = 1000} };
                       
    Video videos2[] = { {.name = "Soccer", .unique_views = 500} };
    
    Viewer viewer = {.username = "Dave", .watched_videos = videos,
                     .watched_videos_size = 2} ;
    
    Viewer view = {.username = "Bob", .watched_videos = videos2,
                     .watched_videos_size = 1};
    
    Viewer *viewers[] = { &viewer, &view };
    printf("%d", count_views(viewers, 2, "Soccer")); /* should print 1 */
}

wanted to iterate through multiple viewers to count the number of views but the first iteration is going correctly but on the second iteration ptr is pointing to null is ptr++ not approporiate for this?

how else should i iterate through that array


Solution

  • The main problem is ptr = *viewers;. You are treating viewers as if it is an array of structs, but it's actually an array of pointers. You have to iterate through that pointer array pointer by pointer - but you do ptr++ which instead increases ptr by the size of a struct. That variable is just confusing you, so just get rid of it:

    int count_views(Viewer **viewers, int viewers_size, char *video_name)
    {
        Video *vid;
        int count=0;
        for (int i=0;i<viewers_size;i++){
            printf("%s ",viewers[i]->username);
            vid=viewers[i]->watched_videos;
            for (int j=0;j < viewers[i]->watched_videos_size;j++){
                printf("%d %d\n",j,viewers[i]->watched_videos_size);
                printf("%s \n",vid->name);
                if (vid->name == video_name){
                    count++; 
                }
                vid++;
            }
        }
        return count;
    }
    

    General best practices is to use loop iterators over pointer arithmetic when possible. In the example above I used viewers[i] instead of incrementing some pointer. More readable and safe.

    Also, gcc non-standard extensions is literally a pox. Keep to standard C and never use useless gcc extensions just for the heck of it. That means change #import to #include.