Frazzled by these peculiar pointer behaviors!

I have been learning C++ by myself and have made significant progress. I need some insight/help however relating to the use of pointers in the application outlined here. With respect to the design of a program for a video store's transactions, I wrote two classes, videoListType and customerListType, that are each derived from a class template, linkedListType<class parameter>, as shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
class videoListType: public linkedListType<videoType>
{
    .
    .
    .
};

class customerListType: public linkedListType<customerType>
{
    .
    .
    .
};

Please note that the parameters videoType and customerType are themselves classes while classes videoListType and customerListType are not class templates!


I wrote a non-class function createVideoList(ifstream& infile, videoListType& videoList) to load video data from a text file, successfully created a linked-list object videoList in the process, and was able to print its contents. Since each customer of the video store could rent one or more videos, I wrote class customerType(derived from another class personType) in such a way that it has a pointer of type videoListType as a data member, as sketchily shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class customerType: public personType
{
public:
   setCustomerInfo(newString fName, newString lName, newString acctNo, videoListType* rVideoList);
    .
    .
    .
  
   customerType(newString fName = "", newString lName = "", newString acctNo = "", rvideoList = NULL);

private:
   newString custAcctNo;
   videoListType* rentedVideoList;
}; 



With the backdrop above, here are my questions:

#1. If after all programming protocols are observed, the code segment below worked for object videoList in function main():

1
2
3
4
5
ifstream infile;  

videoListType videoList;
createVideoList (infile, videoList);
videoList.print();


Question: How come it's not working when I used instead a declared pointer (i.e. videoListPtr) to the object as shown (after making all required changes to declarations, formal parameters, etc, of course):

1
2
3
4
videoListType* videoListPtr;

createVideoList(infile, videoListPtr);
videoListPtr->print();


#2. Please consider the following codes I wrote relating to the non-class function createCustomerList(ifstream& infile, customerListType customerList):

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
void createCustomerList(ifstream& infile, customerListType& customerList)
{
    newString FirstName;        
    newString LastName;               
    newString AcctNo;              
    char ch;
    videoListType* q = NULL;
    
    customerType newCustomer;  
    
    cout<<"Inside fn createCustomerList!"<<endl<<endl;
    
    infile>>FirstName;         
  
    while (infile)
    {
        infile>>LastName;
        infile>>AcctNo;                   
        infile.get(ch);                     //mopping up the newline character after last read
        
        loadCustomerRentedVideoList(infile, q);
        
        newCustomer.setCustomerInfo(FirstName, LastName, AcctNo, q);
        customerList.insertLast(newCustomer);           //function inherited from base class linkedListType 
  
    
        infile>>FirstName;
    }//end while
    cout<<"After completing the whole reading in fn createCustomerList!"<<endl;
    cout<<"pointer q in fn is = "<<q<<endl<<endl;
    
}



void loadCustomerRentedVideoList(ifstream& infile, videoListType*& p_VideoList)  
{                                                            
    char Title[50];
    char Star1[50];
    char Star2[50];
    char Producer[50];
    char Director[50];
    char ProductionCo[70];
    char ch, ch1, ch2;
    int InStock;
    videoType newVideo;
    videoListType videoList;
    
    cout<<"Inside fn loadCustomerRentedVideoList!"<<endl<<endl;  
  
    infile.get(ch1);
    ch2 = infile.peek();
  
    while (isalnum(ch1) && isalnum(ch2))
    {
        infile.putback(ch1);     
        infile.get(Title, 50);
        infile.get(ch);       //for the newline character of preceding input data
        infile.get(Star1, 50);
        infile.get(ch);
        infile.get(Star2, 50);
        infile.get(ch);
        infile.get(Producer, 50);
        infile.get(ch);
        infile.get(Director, 50);
        infile.get(ch);
        infile.get(ProductionCo, 70);
        infile.get(ch);
        infile>>InStock;         //different from the rest since InStock is an integer
        infile.get(ch);
           
        newVideo.setVideoInfo(Title, Star1, Star2, Producer, Director, ProductionCo, InStock);
        videoList.insertLast(newVideo);           //function inherited from base class linkedListType
         
        infile.get(ch);       //to lick up the newline character btw video info blocks
        infile.get(ch1);
        ch2 = infile.peek();
    }//end while
    
    
    
    p_VideoList = &videoList;
    
    cout<<"Just before returning from fn loadCustomerRentedVideoList!"<<endl;
    cout<<"p_VideoList in fn = "<<p_VideoList<<endl<<endl;
}



The output yielded by the two functions above puzzled me a lot! Here it is:

Inside fn createCustomerList!

Inside fn loadCustomerRentedVideoList!

Just before returning from fn loadCustomerRentedVideoList!
p_VideoList in fn = 0x28f7a0

Inside fn loadCustomerRentedVideoList!

Just before returning from fn loadCustomerRentedVideoList!
p_VideoList in fn = 0x28f7a0

Inside fn loadCustomerRentedVideoList!

Just before returning from fn loadCustomerRentedVideoList!
p_VideoList in fn = 0x28f7a0

After completing the whole reading in fn createCustomerList!
pointer q in fn is = 0x28f7a0


Question: Why are the values of the pointers the same especially since each call to function loadCustomerRentedVideoList() is for a different customer??!! Each trip to function load...() successfully read the videos associated with each customer; but why are they all lumped together apparently since the pointer values returned are all the same?? I later observed I could not print the information of the customer list; the first name, last name, and account number of the first customer print, then the program freezes up and aborts!!

Please, help guys! I am at a crossroads!!
Question: How come it's not working when I used instead a declared pointer (i.e. videoListPtr) to the object as shown (after making all required changes to declarations, formal parameters, etc, of course):

"It's not working" is a spectacularly unhelpful description. You could easily describe for us the behaviour you're seeing, and how it differs from the expected behaviour, to help us more easily diagnose your problem.

You also haven't shown us the code for the functions you call in the code that "isn't working" , createVideoList() and videoListType::print().

Why would you withhold all this information from us?

Given your unwillingness to give us the information we need, I'm going to have to take a wild guess. Is it possible that you're passing videoListPtr into createVideoList() by value? Are you setting a value for videoListPtr inside the function, but not properly passing that value back to the calling code?
MikeyBoy wrote:
Why would you withhold all this information from us?
Given your unwillingness to give us the information we need, ...


It's laughable how you picked holes with just only one of my questions (Qn#1) based on lack or paucity of information while, in the same breadth, completely ignored the other question (Qn#2) that had all the needed info, including program code and output!! Anyway, answering your question, I did not pass the pointer to function createVideoList() by value; I passed it by reference. Anywhere object videoList invokes a function using the member access operator(.), I changed to member access operator arrow(->) for the pointer videoListPtr. For example,

videoList.insertLast(); becomes videoListPtr->insertLast();

insertLast() is a member function from the base class linkedListType

Moreover, by "it's not working," I meant that the display window for the results during program execution just freezes up; only the cursor is blinking or just sheer black screen!
Last edited on
Your initial posting was rather long -- and I have learned that the aphorism "people don't read squat" is pretty appropriate everywhere I go.

p_VideoList = &videoList;

You are assigning the address of a local object (== temporary object) to the result of your variable. The fact that you can test it and get the same pointer value just means that you happen to call the function in a way that the function's stack frame is in the same place on the stack as it was the first time you called it. (If that doesn't make sense, don't worry.)

The thing to get is that if you want to return the address of an object, said object must have a lifetime greater than the function. There are two ways to do that:

    1. Return the address of a global variable

    2. Get memory from the heap and return that.

Examples:

1
2
3
4
5
6
7
8
9
10
11
// Method 1:     Global Objects
// Advantage:    No memory leaks
// Disadvantage: Can only do this once

int my_global_foo;

void get_my_foo( int*& result )
{
  result = &my_global_foo;
  *result = 12;  // my_global_foo = 12;
}
1
2
3
4
5
6
7
8
9
// Method 2:     Heap Allocated Objects
// Advantage:    Can do this as many times as there is memory available
// Disadvantage: Memory leaks possible -- caller must know to deallocate memory

void get_my_foo( int*& result )
{
  result = new int;
  *result = 12;
}

Hope this helps.
@Duoas:
Thanks a lot for your post; it really helped! I knew about the concept of dynamic memory allocation as Method 2 of your post evinces; I just did not think it was going to be needed/appropriate for what I was trying to do. I have been able to resolve the issue I was having within the two functions earlier; and surprisingly, a different but related problem in another part of the program was resolved also.

I have a question for you: How does one know which pointer style

(i.e. ptr = &dataVariable or ptr = new dataType)

to use in a function or program?? If you have any useful online literature/ reference regarding this, it'd be appreciated.

Finally, what is your view about the first question (Question #1) in my penultimate post? Thx
Last edited on
re: pointer style
It isn't a matter of style, it is a matter of what you are doing.

ptr = &dataVariable; // get address of extant object and assign it to 'ptr'

ptr = new dataType; // create new object on heap and assign it's address to 'ptr'

This site's tutorial is pretty good reading.


re: Q1
I suspect it is because you did not create an object of type videoListType. You only created a pointer to one.

That's like some archer saying, "where's the apple", and the lackey answering, "over there" and pointing in some random location. Something's going to get shot, but it is not likely to be an apple.

The only other reading I can offer at the moment is here:
http://www.cplusplus.com/faq/sequences/strings/c-strings-and-pointers/

It talks specifically about c-strings, but the details about pointers and the actual character array data (the object) apply.

Hope this helps.
Topic archived. No new replies allowed.