Weird Problem with array of vector <char *>


Hi everyone,

I'm a moderately experienced C++ programmer and a network engineer. I’m having a weird problem with using an array of vector<char *>, which I’ve never tried to work with before. I’m working on a program which does the following:

1. Inputs and parses a file called PREFIX_FILE, which contains all the prefix information on my network.
2. For every line, extracts the first token as a string and the second as an int. The value that int will always be from 0 to 32. (33 total)
3. The program creates an object called MaskObject, which is essentially just an array of 33 vector<char *>’s.
4. For each string read from the file, the program stores the string into the corresponding vector. (For example, strings 10.10.10.0, 20.20.20.0, and 30.30.30.0 should be stored into vector 22 in the MaskObject; string 40.40.40.0 should be stored into vector 30, and 50.50.50.0 and 60.60.60.0 should be stored into vector 32

All of this seems to work just fine, except for Step 4. The funny thing is when the program completes, the correct number of strings are stored in the correct vectors... but all the strings have the same value of the last string only!!! (i.e., all stored strings are 60.60.60.0 and I lose the values of the first five strings.)

I can’t figure this out. My first instinct was all strings were being stored correctly, but my THEArrayDisplay() function must be printing out only the last string value. But I’ve carefully checked, and I’m not certain that’s the case now. There’s something weird going on that I can’t see.

Below is my input file (PREFIX_FILE), the program output, and finally the code itself. Can anyone tell me what’s going on here?

Many thanks!
-Pete


======================================================================================
--------------------------------------------------------------------------
PREFIX_FILE
--------------------------------------------------------------------------
10.10.10.0;22
20.20.20.0;22
30.30.30.0;22
40.40.40.0;30
50.50.50.0;32
60.60.60.0;32

--------------------------------------------------------------------------
======================================================================================

Here is the program outout:

======================================================================================
bash-3.00$ ./runprogram

o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
Mask /0: (0)
Mask /1: (0)
Mask /2: (0)
Mask /3: (0)
Mask /4: (0)
Mask /5: (0)
Mask /6: (0)
Mask /7: (0)
Mask /8: (0)
Mask /9: (0)
Mask /10: (0)
Mask /11: (0)
Mask /12: (0)
Mask /13: (0)
Mask /14: (0)
Mask /15: (0)
Mask /16: (0)
Mask /17: (0)
Mask /18: (0)
Mask /19: (0)
Mask /20: (0)
Mask /21: (0)
Mask /22: (3) 60.60.60.0(22,0) - 60.60.60.0(22,1) - 60.60.60.0(22,2) -
Mask /23: (0)
Mask /24: (0)
Mask /25: (0)
Mask /26: (0)
Mask /27: (0)
Mask /28: (0)
Mask /29: (0)
Mask /30: (1) 60.60.60.0(30,0) -
Mask /31: (0)
Mask /32: (2) 60.60.60.0(32,0) - 60.60.60.0(32,1) -
o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o

bash-3.00$
======================================================================================

And here is the code:

======================================================================================
--------------------------------------------------------------------------
MaskObject.h
--------------------------------------------------------------------------


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
class MaskObject {
 public:
  //Constructors
    MaskObject();
    ~MaskObject();

  //Accessors
    void AddToTHEArray(int Mask, char * IPAddr);
    void THEArrayDisplay();

 protected:
    vector<char *> THEArray[33];

};



void MaskObject::AddToTHEArray(int Mask, char * IPAddr)
  {
     // All we do is push_back the submitted string
     THEArray[Mask].push_back(IPAddr);
  }



void MaskObject::THEArrayDisplay()
{
  cout<<"\to-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o\n";
  for(int i=0; i<33; i++)
    {
      cout<<"Mask /"<<i<<":  ("<<THEArray[i].size()<<")  ";
      for(unsigned int j=0; j<THEArray[i].size(); j++)
        {
          cout<<THEArray[i][j]<<"("<<i<<","<<j<<") - ";
        }
      cout<<"\n";
    }
  cout<<"\to-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o\n";
}




--------------------------------------------------------------------------
ReadTheFile.h
--------------------------------------------------------------------------


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
void ReadTheFile(MaskObject* PtrMaskLibrary)
{
  // Variable Declaration...
  string Line, Value;  int Mask;
  char * IPAddr = (char*) malloc (sizeof(char) * 15);  memset(IPAddr,0,15);
  vector<string> ValRow;  vector<string>* PtrValRow = &ValRow;


  // We import all the Prefixes from input file "PREFIX_FILE"...
  ifstream In_Prefixes(PREFIX_FILE);
  while (getline(In_Prefixes, Line))
    {
      // Because each line in PREFIX_FILE has multiple values, we tokenize the line and extract
      // what we want into ValRow
      istringstream linestream(Line);
      ValRow.clear();
      while(getline(linestream, Value, ';'))
        { ValRow.push_back(Value); }

      // ValRow[0] is the string containing the Prefix address; this is what I ultimately want
      // to load and store into the MaskObject vector (above)
      IPAddr = strcpy(IPAddr, ((*PtrValRow)[0]).c_str());

      // Here's where I send the Prefix to my MaskObject... and the trouble arises!
      PtrMaskLibrary->AddToTHEArray(Mask, IPAddr);         // <-- TROUBLE IS HERE!!!

    }  // end of "while (getline(In_Prefixes, Line))"
}




--------------------------------------------------------------------------
Main.cpp
--------------------------------------------------------------------------


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "MaskObject.h"
#include "ReadTheFile.h"


int main(int argc, char * argv[])
{
  // Create MaskObject object...
  MaskObject* PtrMaskLibrary = new MaskObject();

  // Read/Parse Input File
  ReadTheFile(PtrMaskLibrary);

  // Print out THEArray Values...
  PtrMaskLibrary->THEArrayDisplay();
}


======================================================================================


1
2
3
4
      IPAddr = strcpy(IPAddr, ((*PtrValRow)[0]).c_str());

      // Here's where I send the Prefix to my MaskObject... and the trouble arises!
      PtrMaskLibrary->AddToTHEArray(Mask, IPAddr);         // <-- TROUBLE IS HERE!!! 


yes, there is a problem there.
You are using the same buffer each time.
So each IPAddr = strcpy(IPAddr, ((*PtrValRow)[0]).c_str()) is overwriting the previous one.
(It also means that all the pointer values added to the mask
1
2
      // Here's where I send the Prefix to my MaskObject... and the trouble arises!
      PtrMaskLibrary->AddToTHEArray(Mask, IPAddr);         // <-- TROUBLE IS HERE!!! 
will be the same value (because you are continually using the same buffer)
yes , you override the same buffer all the time.Besides you seemed to forget about dealing with the Mask varible .Here are the codes modified form yours. I ran it without problem with
my visual studio 2008
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
#ifndef _MASK_OBJECT_H
#define _MASK_OBJECT_H
#include <vector>
#include <iostream>
#include <cstdlib>
#include <cassert>
using namespace std;
class MaskObject {
 public:
  //Constructors
  //  MaskObject();
 //   ~MaskObject();

  //Accessors
    void AddToTHEArray(int Mask, char * IPAddr);
    void THEArrayDisplay();

 protected:
    vector<char *> THEArray[33];

};


void MaskObject::AddToTHEArray(int Mask, char * IPAddr)
  {
     // All we do is push_back the submitted string
      char* dstPtr = (char*)(malloc)(15*sizeof(char));
      strcpy(dstPtr,IPAddr);
     THEArray[Mask].push_back(dstPtr);
  }



void MaskObject::THEArrayDisplay()
{
  cout<<"\to-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o\n";
  for(int i=0; i<33; i++)
    {
      cout<<"Mask /"<<i<<":  ("<<THEArray[i].size()<<")  ";
      for(unsigned int j=0; j<THEArray[i].size(); j++)
        {
          cout<<THEArray[i][j]<<"("<<i<<","<<j<<") - ";
        }
      cout<<"\n";
    }
  cout<<"\to-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o\n";
}
#endif 


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
#ifndef _READ_THE_FILE_H
#define _READ_THE_FILE_H
#include <string>
//#include <strstream>
#include <vector>
#include <iostream>
#include <string.h>
#include <fstream>
#include <sstream>
#include "maskobject.h"
using namespace std;
void ReadTheFile(MaskObject* PtrMaskLibrary)
{
  // Variable Declaration...
  string Line, Value;  int Mask=0;
  char * IPAddr = (char*) malloc (sizeof(char) * 15);  memset(IPAddr,0,15);
  vector<string> ValRow;  vector<string>* PtrValRow = &ValRow;


  // We import all the Prefixes from input file "PREFIX_FILE"...
  ifstream In_Prefixes("PREFIX_FILE");
  while (getline(In_Prefixes, Line))
    {
      // Because each line in PREFIX_FILE has multiple values, we tokenize the line and extract
      // what we want into ValRow
      istringstream linestream(Line);
      ValRow.clear();
      while(getline(linestream, Value, ';'))
        { 
            ValRow.push_back(Value); 
            linestream>>Mask;				//wow,you have to assign the Mask varible

        }

      // ValRow[0] is the string containing the Prefix address; this is what I ultimately want
      // to load and store into the MaskObject vector (above)
      IPAddr = strcpy(IPAddr, ((*PtrValRow)[0]).c_str());

      // Here's where I send the Prefix to my MaskObject... and the trouble arises!
      PtrMaskLibrary->AddToTHEArray(Mask, IPAddr);         // <-- TROUBLE IS HERE!!!

    }  // end of "while (getline(In_Prefixes, Line))"
}
#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "MaskObject.h"
#include "ReadTheFile.h"


int main(int argc, char * argv[])
{
  // Create MaskObject object...
  MaskObject PtrMaskLibrary;

  // Read/Parse Input File
  ReadTheFile(&PtrMaskLibrary);

  // Print out THEArray Values...
  PtrMaskLibrary.THEArrayDisplay();
}

hope this helps you out.
Topic archived. No new replies allowed.