Thread: Returning a double pointer help.

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    114

    Returning a double pointer help.

    Hi,

    I've racked my brain trying to figure this out. I clearly don't have an understanding of how pointers work.

    I'm trying to return a double pointer from a function. Here is my current code:

    Code:
    // Declare includes.
    #include <errno.h>
    #include <libgen.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // Declare defines.
    #define FILENAME_SIZE                100
    #define MAX_OLD_DOWNLOADS             10
    #define PROGRAM_NAME_SIZE             50
    #define YOUTUBE_DATA_DIRECTORY         "/dea/youtube_data/"
    
    // Declare global variables.
    char program_name[PROGRAM_NAME_SIZE + 1] = {0};
    
    // Declare function prototypes.
    char ** get_downloaded_list (char *account);
    
    int main (int argc, char *argv[])
    {
    // Decalre variables.
        char **downloaded = {0};
    
    // Get program name for error reporting.
        strcpy(program_name, basename(argv[0]));
    
    // Check number of arguments.
        if(argc != 1)
        {
            fprintf(stderr, "Usage: %s\n", program_name);
            exit(EXIT_FAILURE);
        }
    
    // Get downloaded videos list.
        downloaded = get_downloaded_list("AlfieAesthetics");
    
    if(downloaded)
        {;}
    
    // Exit cleanly.
        exit(EXIT_SUCCESS);
    }
    
    char ** get_downloaded_list (char *account)
    {
    // Declare variables.
        int counter = 0;
        FILE *fp = NULL;
        char filename[FILENAME_SIZE + 1] = {0};
        static char downloaded[MAX_OLD_DOWNLOADS][25] = {0};
    
    // Build the filename
        strcpy(filename, YOUTUBE_DATA_DIRECTORY);
        strcat(filename, account);
    
    // Open the data file for reading.
        if((fp = fopen(filename, "r")) == NULL)
        {
            fprintf(stderr, "%s: get_downloaded_list error: fopen failed (%s) (%s)\n", program_name, strerror(errno), filename);
            exit(EXIT_FAILURE);
        }
    
    // Loop through all lines in the file.
        while(fgets(downloaded[counter], 25, fp) != NULL && counter < MAX_OLD_DOWNLOADS)
        {
    // Remove trailing newline.
            downloaded[counter][strlen(downloaded[counter]) - 1] = '\0';
    // Advance counter.
            counter++;
        }
    
    // Set end marker if list is not maxed out.
        if(counter != MAX_OLD_DOWNLOADS)
            downloaded[counter][0] = '\0';
    
    // Close the data file.
        fclose(fp);
    
    // Return the list.
        return(downloaded);
    }
    The error received is:
    Code:
    dea_get_youtube.c: In function ‘get_downloaded_list’:
    dea_get_youtube.c:81:8: error: returning ‘char (*)[25]’ from a function with incompatible return type ‘char **’ [-Werror=incompatible-pointer-types]
       81 |  return(downloaded);
          |        ^
    compilation terminated due to -Wfatal-errors.
    cc1: all warnings being treated as errors
    Can someone please help me understand what is going on here? Or at least reference some resource that might help me understand?

    Ty.

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    505
    Multi-dimensional arrays are an advanced feature of C, and they don't work wth the rest of the language as you think they should. Unfortunately most C primers introduce multi-dimensional arrays immediately after single dimensional arrays, ignorin gtheir complexities.

    A double pointer is not really a pointer to a 2D array. It is a related idea, but not the same thing. A double pointer is a pointer to a pointer, or a pointer to a list of pointers. You often use a char ** for a list of strings. Each string should be allocated separately (e.g. by a call to malloc), then the list itself needs to be allocated.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I'm trying to return a double pointer from a function. Here is my current code:
    But you have a 2D array - which isn't the same thing.

    char a[N] becomes a char *
    but
    char a[R][C] becomes char (*)[C], not char **. The array-becomes-pointer rule only applies to the left-most dimension, not all of them.

    If you thought returning a ** was mind-bending enough, you're really not going to like returning a pointer to a 2D array.
    Code:
    // Declare includes.
    #include <errno.h>
    #include <libgen.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // Declare defines.
    #define FILENAME_SIZE                100
    #define MAX_OLD_DOWNLOADS             10
    #define PROGRAM_NAME_SIZE             50
    #define YOUTUBE_DATA_DIRECTORY         "/dea/youtube_data/"
    
    // Declare global variables.
    char program_name[PROGRAM_NAME_SIZE + 1] = {0};
    
    // Declare function prototypes.
    char (*get_downloaded_list (char *account))[25];
    
    int main (int argc, char *argv[])
    {
    // Decalre variables.
        char (*downloaded)[25] = {0};
    
    // Get program name for error reporting.
        strcpy(program_name, basename(argv[0]));
    
    // Check number of arguments.
        if(argc != 1)
        {
            fprintf(stderr, "Usage: %s\n", program_name);
            exit(EXIT_FAILURE);
        }
    
    // Get downloaded videos list.
        downloaded = get_downloaded_list("AlfieAesthetics");
    
        if(downloaded)
        {;}
    
    // Exit cleanly.
        exit(EXIT_SUCCESS);
    }
    
    char (*get_downloaded_list (char *account))[25]
    {
        // Declare variables.
        int counter = 0;
        FILE *fp = NULL;
        char filename[FILENAME_SIZE + 1] = {0};
        static char downloaded[MAX_OLD_DOWNLOADS][25] = {0};
    
        // Build the filename
        strcpy(filename, YOUTUBE_DATA_DIRECTORY);
        strcat(filename, account);
    
        // Open the data file for reading.
        if((fp = fopen(filename, "r")) == NULL)
        {
            fprintf(stderr, "%s: get_downloaded_list error: fopen failed (%s) (%s)\n", program_name, strerror(errno), filename);
            exit(EXIT_FAILURE);
        }
    
        // Loop through all lines in the file.
        while(fgets(downloaded[counter], 25, fp) != NULL && counter < MAX_OLD_DOWNLOADS)
        {
            // Remove trailing newline.
            downloaded[counter][strlen(downloaded[counter]) - 1] = '\0';
            // Advance counter.
            counter++;
        }
    
        // Set end marker if list is not maxed out.
        if(counter != MAX_OLD_DOWNLOADS)
            downloaded[counter][0] = '\0';
    
        // Close the data file.
        fclose(fp);
    
        // Return the list.
        return(downloaded);
    }

    But if you really want the char** route (which is more flexible in the long run), then:
    Code:
    char **get_downloaded_list (char *account)
    {
        // Declare variables.
        int counter = 0;
        FILE *fp = NULL;
        char filename[FILENAME_SIZE + 1] = {0};
        char **downloaded = malloc(MAX_OLD_DOWNLOADS * sizeof(*downloaded));
        char buff[25];
    
        // Build the filename
        strcpy(filename, YOUTUBE_DATA_DIRECTORY);
        strcat(filename, account);
    
        // Open the data file for reading.
        if((fp = fopen(filename, "r")) == NULL)
        {
            fprintf(stderr, "%s: get_downloaded_list error: fopen failed (%s) (%s)\n", program_name, strerror(errno), filename);
            exit(EXIT_FAILURE);
        }
    
        // Loop through all lines in the file.
        while(fgets(buff, sizeof(buff), fp) != NULL && counter < MAX_OLD_DOWNLOADS)
        {
            // Remove trailing newline.
            buff[strlen(buff)-1] = '\0';
    
            // save it
            downloaded[counter] = malloc( strlen(buff) + 1 );
            strcpy(downloaded[counter], buff);
    
            // Advance counter.
            counter++;
        }
    
        // Set end marker if list is not maxed out.
        if(counter != MAX_OLD_DOWNLOADS)
            downloaded[counter] = NULL;
    
        // Close the data file.
        fclose(fp);
    
        // Return the list.
        return(downloaded);
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with function and returning double
    By Kaza in forum C++ Programming
    Replies: 9
    Last Post: 03-01-2019, 08:31 AM
  2. Returning a double matrix
    By adarpodracir in forum C Programming
    Replies: 5
    Last Post: 03-25-2012, 03:20 PM
  3. Double liked list and double pointer
    By saillesh.sabari in forum C Programming
    Replies: 1
    Last Post: 12-10-2010, 11:03 AM
  4. Replies: 3
    Last Post: 10-30-2009, 04:41 PM
  5. returning a double array [][]
    By Morrow in forum C++ Programming
    Replies: 4
    Last Post: 09-29-2004, 10:01 AM

Tags for this Thread