Passing a Dynamic Array of Pointers to a Function

Hey guys, so I'm trying to Dynamically Allocate an array of Pointers, and then pass that to a function so that I can store addresses of some integers.

I am pretty new with the dynamic allocation and pointers, but from my understanding, since I have an Array of pointers (int**), it needs to be (int***) in the parameter to my function, and I need to pass the address in my function call. I would really appreciate it if someone could tell me where I might be going wrong.

1
2
3
4
5
   // Main
   int** myPtr;
   myPtr = (int**) malloc (sizeof (int*) * numberShowings);
   
   displayShowTimes (foundPtr, &showingCounter, &myPtr);


1
2
3
4
5
6
7
8
// The function in question
void displayShowTimes (node_t* foundPtr, int* showingCounter, int*** myPtr) {

         (*myPtr)[*showingCounter] = &foundPtr->movie.maxSeating[i];
         (*showingCounter)++;
         printf ("Seating: %d\n", (*myPtr)[*showingCounter]);
 
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// These are my Node and Movie structs that are mentioned above
typedef struct node_t {
   movie_t movie;
   struct node_t* nextPtr;
   struct node_t* prevPtr;
} node_t;

typedef struct {
   char title[MAX_STRING];
   int lengthHour; // 24-hour time
   int lengthMinute;
   char rating[MAX_RATING];
   int numShowings;
   mytime_t time[MAX_SHOWINGS];
   int maxSeating[MAX_SHOWINGS];
} movie_t;


I'm going to assume this is C code. Also, I'd suggest trying to find a way to redesign your code: you do not want to be a 3-star programmer. Even ignoring readability (which should never be ignored), you'll probably have a fairly significant performance impact from the number of redirections you'll have.

I can see a number of possible problems with your displayShowTimes function. Firstly, you are incrementing showingCounter and then printing the contents of the array at that point, which (from your example) appears to be uninitialized memory. Have you tried swapping lines 5 and 6?

On line 6, you're trying to use the %d format modifier for an int*; probably, printing the address of the pointer wasn't what you meant anyway. You need another dereference.

The use of i on line 4 could be suspect, too; a single letter identifier is a horrible choice for a global, and globals themselves should be last-resort options.

As an aside, you only need to pass a pointer to your array if you want to change the array itself, that is, perform a realloc or free or something of that ilk. Your function doesn't do anything like this, so passing the array itself is fine.

Here's a fixed-up version of your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
// main
int** seatCount; // please use useful variable names
seatCount = (int**)malloc(sizeof(int*) * numberShowings);

displayShowTimes(foundPtr, &showingCounter, seatCount, showID);

// ...

void displayShowTimes(node_t* foundPtr, int* showingCounter, int** seatCount, int showID) {
    seatCount[*showingCounter] = &(foundPtr->movie.maxSeating[showID]);
    printf("Seating: %d\n", *(seatCount[*showingCounter]));
    (*showingCounter)++;
}

Or something like that. You may want to throw some error-checking in, too.
Last edited on
using only movie name and show time as the ctor of movie objects - extend as applicable and impose strict input validation at all stages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <string>
#include <ctime>
#include <limits>
constexpr auto SIZE = 3;

struct Movie
{
    std::string m_name;
    std::tm m_showTime;

    Movie(const std::string& name, const int& hr, const int& minute) : m_name(name)
    {
        m_showTime.tm_hour = hr;
        m_showTime.tm_min = minute;
    }

    ~Movie(){std::cout << "Bye " << m_name << "\n";}
};
    void displayName(Movie** ptr_Array)
{
    for (size_t i = 0; i < SIZE; ++i)
    {
        std::cout << (*(*(ptr_Array+i))).m_name << " starts "
        << (*(*(ptr_Array+i))).m_showTime.tm_hour << ":" << (*(*(ptr_Array+i))).m_showTime.tm_min << "\n";
        //inner dereference gives array element which is a pointer
        //outer dereference dereferences this array element to the underlying Movie object
    }
}
int main()
{
    Movie** ptr_Array = new Movie*[SIZE];
    for (size_t i = 0; i < SIZE; ++i)
    {
        std::cout << "Enter movie name \n";
        std::string name{};
        getline(std::cin, name);
        std::cout << "Enter start hr (24 hr clock) \n";
        int hr;
        std::cin >> hr;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "Enter start minute \n";
        int minute;
        std::cin >> minute;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        *(ptr_Array + i) = new Movie(name, hr, minute);//overload ctor as required
    }

    displayName(ptr_Array);
    std::cout << "\n";
    for (size_t i = 0; i < SIZE; ++i)
    {
        delete ptr_Array[i];//deletes the Movie objects
    }
    delete [] ptr_Array;//deletes the dynamically allocated array
}
Thank you so much for your help, I implemented your solution and it works perfectly. Sorry for the poor readability, I've been at this for hours tonight and I was at the point where I was getting sloppy and trying literally anything to get it to work. I will admit that I do have a hard time coming up with meaningful names for some of my variables, I will try to work on that.

As an aside, you only need to pass a pointer to your array if you want to change the array itself, that is, perform a realloc or free or something of that ilk.

I'm definitely putting that in my notes

Have you tried swapping lines 5 and 6?

You're a hero, I might be able to get some sleep after all tonight.
Last edited on
I'm sorry I did not mention more guys, all the data for Movie_t is coming straight from a binary input file, I have a lot more code than this, I only posted what I thought would be relevant to the problem I had because I did not want to just post pages and pages of code.

I do have a second question though if you guys are willing. The only reason I created this dynamic array:
1
2
int** seatCount; // please use useful variable names
seatCount = (int**)malloc(sizeof(int*) * numberShowings);


... is because I need to be able to decrement the Number of Seats, depending on what the User Inputs. Meaning if they enter 1, I need to decrement the first show time, or if they enter 7, I need to decrement the 7th showtime, so on. So I'm going to use the index of this new array to assign them all that way.

This seems like its unnecessary but I'm just not sure of another way to tie the user's input to the specific Showtime that I want to decrement. Due to the parameters of the assignment, I cannot change any of the Structs.

I'm not even sure if this makes sense. Thanks for your help anyway guys.

EDIT: I should probably mention that I'm also using a Doubly Linked List:
1
2
3
4
typedef struct {
   node_t* headPtr;
   node_t* tailPtr;
} dbl_linked_list_t;

Last edited on
Topic archived. No new replies allowed.