Link to home
Start Free TrialLog in
Avatar of apatia
apatia

asked on

Problem maintaining pointer assignment

Here's what I'm trying to do - I read a file line-by-line and I check each line to determine if it is the start of a section, the end of a section or neither.  My section heading and endings (start and end) are stored in a linked list.  The problem is the following:I have to pointers to the linked list. One pointer always points to the head of the list. The other pointer is either null or points to the "link" where the section head was found.  So, I read in a line from the file, call the processFile function. The head and current pointers are passed to the function.   If a section start is found, I expect that the curr_obj pointer would be set to point to the appropriate link. But it doesn't. After the function runs, curr_obj is always NULL, even when a start is found.  I'm not sure what's wrong with my logic. I'd appreciate any help.

//test.h
struct obj {  //
  char *start;
  char *end;
  obj *next;
}

class Test {
public:
void main(char *filename);
private:
boolean processLine(char *line, obj *list, obj *current);
}

//Test.cpp

boolean Test::processLine(char *line, obj *list, obj *current) {
  bool result = false;
  if (current != 0) {   //start found, check for matching end
      if (strstr(line, current->end) != NULL) {   //search for "end" in "line"
             current = 0;
             result = false;                      
      }
      else
             result = true;
  }
  else {          //check for start
     current = list;
     while (current != 0  && !result) {
          if (strstr(line,current->start) {
             result = true;
       }
          else
             current = current->next;
     }
  }
  return result;
}//end processLine

void Test::main(char * filename) {
   char _line[80];
   obj *head = 0;
   obj *curr_obj = 0;
   bool inSection = false;
   
  //open file...
  //read in line of file...
  while (!EOF) {
      ...
      inSection =  processLine(_line, head, curr_obj);
      if (curr_obj != 0) {   // if start was found in function, curr_obj should point to "link" in the list
         ...
       }
      //read in next line of file ...
  }

}//end main
Avatar of Kocil
Kocil

/* add double ** on current */
/* use *current inside the function */
boolean Test::processLine(char *line, obj *list, obj **current) {
 bool result = false;
 if (*current != 0) {
     if (strstr(line, *current->end) != NULL) {
            *current = 0;
            result = false;                      
     }
     else
            result = true;
 }
 /* and so on */

 ...
}//end processLine


/* call it by using & */

void Test::main(char * filename) {
  char _line[80];
  obj *head = 0;
  obj *curr_obj = 0;
  bool inSection = false;

   ...
   inSection =  processLine(_line, head, &curr_obj);
   if (curr_obj != 0) {  
        ...
   }
 }

ASKER CERTIFIED SOLUTION
Avatar of Kocil
Kocil

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi, apatia.

The variable curr_obj defined in the main function remains 0 after calling the processLine function because the function receives a copy of a value of the curr_obj as the argument current. Therefore you can not change the value of curr_obj in the main through the current in the processLine. In general, this calling method is called as "call by value".

You can change the curr_obj in the processLine by using "call by reference". For that purpose, use a pointer or reference to the variable.

Using reference, processLine can be defined as follows:

boolean Test::processLine(...., obj*& current){
...
}

Now the current is an alias of the curr_obj, you can change the curr_obj's value through it and no other modifications are required for the codes. A notation "type& ref" declares ref as a reference to a variable of the type.

Using pointer, processLine can be defined as follows:

boolean Test::processLine(...., obj** current) {
...
}

In this case, the current points to curr_obj and you can change the curr_obj's value through the pointer. But you need to change the notation of the current to *current in the processLine and the processLine(...., curr_obj) to processLine(...., &curr_obj) in the main.

You can use whichever of reference and pointer as your preference. Using pointer is my preference because it makes clear that the function modifies the pointed object.

Here's a sample code:

#include <iostream>
#include <string>

//call by value
void f(std::string s){
s = "f";
}

//call by reference using a reference
void g(std::string& s){
s = "g";
}

//call by reference using a pointer
void h(std::string* s){
*s = "h";
}

int main(){
std::string s = "original value";

f(s);
std::cout << "s = " << s << " after f(s) was called.\n";

g(s);
std::cout << "s = " << s << " after g(s) was called.\n";

h(&s);
std::cout << "s = " << s << " after h(&s) was called.\n";

return 0;
}

Sample code output:

s = original value after f(s) was called.
s = g after g(s) was called.
s = h after h(&s) was called.

Hope this helps.
Well long written yukapapa.
I was too lazy :)

Avatar of apatia

ASKER

Kocil - thank you for the quick response. Your second answer worked for me.

Yukapapa - thank you for the thorough explanation.

I will accept Kocil's comment as the answer AND I will post a request to have Yukapapa awarded  250 since the comment was so informative.

Thanks again everyone!
I'm sorry to repeat the Kocil's comments. I didn't know Kocil made answers for the question. As he indicated, my comment is too long to describe the solution. In fact, I am not a native English speaker. I am posting comments for the questions to learn English, not for points. I was afraid that the comment might include ill English. But I feel relieved to hear from apatia and Kocil. Thanks.
Per request in https://www.experts-exchange.com/questions/20547275/Please-split-points.html the points in this question have been reduced from 500 to 250.

apatia,

Here's what you do now:
1. In this topic area, ask a new question worth 250 points entitled "For yukapapa re: 20547103" and put the URL to this question in the body.
2. Come back to this question and accept the comment of Kocil as an answer. Leave a comment that directs yukapapa to the "points for" question.
3. When yukapapa comments in the new question, accept that as an answer.

That should take care of you.

Netminder
EE Admin
Wow the best typing/point for me so far.

one '&' worth 250 point !

Thanks man, and give me and A please.
Avatar of apatia

ASKER

Yukapapa,
for points please see the following question:
https://www.experts-exchange.com/questions/20547810/For-yukapapa-re-20547103.html