passing back an char[][]??

Ok till I get to out main database I was writing a quick hack.  Anyhow what I have is a DB class to returns some basic things.  One thing I wanted to get back is an and array of char*.  

So in the DB class I have a struct { ... char x[5][50] }

somehow I want to pass back a pointer to this.  I tried char** tried void*. gave up on that.  then I tried using char** and some combination of new char*[5] then new char[50] couldn't seem to get it to allocate.  How can I do any of this?

In otherwords I want to pass back a list of strings.  I don't care how.  I know I shouldn't be passing a pointer back, but the class will be going away soon.
micahAsked:
Who is Participating?
 
Answers2000Connect With a Mentor Commented:
Maybe this is way out in left field,

 but why not pass back either a point to the structure or an array/vector of strings (or reference/pointer to one)


0
 
ecwCommented:
make a typedef to an [5][50] array of chars, and get you func to return a pointer to this type ie.:

typedef char x_t[5][50];

x_t *func(DB &d)
{
return &d.x;
}
0
 
nietodCommented:
ecw's answer is right according to what you requested.  However, waht you asked for might not be what you want.  In many cases and array of strings is best implimented using an array of character pointers, that is, by using "char * []".  Wethor or not that is better depends on what you are trying to do. If you supply more details as to the nature of the data and the way in which it will be used, I might be able to ofter some suggestions.  In any case, ecw has provided a solution that will work.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
ecwCommented:
Yeah but if you store a char[][] in a class, you know that's what you get with every instance of the class- no further memory allocs needed.  My preference is to store things as char*[], or char**, because I hate boundaries, but it is not always appropriate, or always worth the effort.
In this case,  the class is "going away soon", so changing the storage layout isn't worth the effort.
0
 
micahAuthor Commented:
char*[] ? not sure I understand you there.  Here is my code


what does it take to pass back _nextHigher?  Once it is passed back how do I print out each element. When I pass it back now it seems to get stomped.  






#ifndef __DB
#define __DB

#include "Device.h"
//
// a realy crappy database
//

struct dbStruct{
  char        _name[50];
  DEVICETYPE  _deviceType;
  char **     _nextHigher;
  int         _nextHigherCount;
  char        _tool[50];

};

class DB{
 public:
  DB();
  ~DB();
  DEVICETYPE getDeviceType(char* name);

  int getNextHigher(char* name,char** data);

  char* getTool(char* name);

 private:
  int findName(char* name);
  dbStruct _data[30];
  int _size;
};
#endif

#include "DB.h"
#include <string.h>

DB::DB(){

  for(int i=0;i<30;i++){
    _data[i]._nextHigher = new char*[5];      
    for(int j=0;j<5;j++)
      _data[i]._nextHigher[j]=new char[50];
  }      
  strcpy(_data[0]._name,"panel");      
  _data[0]._deviceType = PANEL;
  strcpy(_data[0]._nextHigher[0],"fastener_p");
  _data[0]._nextHigherCount=1;
  strcpy(_data[0]._tool,"NULL");

  strcpy(_data[1]._name,"ratchet");                  
  _data[1]._deviceType = ROTATIONAL_TOOL;
  strcpy(_data[1]._nextHigher[0],"NULL");
  _data[1]._nextHigherCount=0;
  strcpy(_data[1]._tool,"NULL");

  strcpy(_data[2]._name,"fastener_p");                  
  _data[2]._deviceType = FASTENER;
  strcpy(_data[2]._nextHigher[0],"NULL");
  _data[2]._nextHigherCount=0;      
  strcpy(_data[2]._tool,"ratchet");

  strcpy(_data[3]._name,"LRU");                  
  _data[3]._deviceType = GENERIC;
  strcpy(_data[3]._nextHigher[0],"fastener_p");
  strcpy(_data[3]._nextHigher[1],"harness_p");
  _data[3]._nextHigherCount=2;      
  strcpy(_data[3]._tool,"NULL");

  strcpy(_data[4]._name,"harness_p");                  
  _data[4]._deviceType = HARNESS;
  strcpy(_data[4]._nextHigher[0],"NULL");
  _data[4]._nextHigherCount=0;      
  strcpy(_data[4]._tool,"NULL");  
 
 _size = 5;
}


DB::~DB(){
  for(int i=0;i<30;i++){
    for(int j=0;j<5;j++)
      delete [] _data[i]._nextHigher[j];
    delete [] _data[i]._nextHigher;
  }      
}

DEVICETYPE        DB::getDeviceType(char* name){
  int i=findName(name);
  if( i >=0 )
      return _data[i]._deviceType;
    return INVALID;
 
}
 

int             DB::getNextHigher(char* name,char** data)
{
  int i=findName(name);
  if(i >=0 ){
    data = &_data[i]._nextHigher;
    return _data[i]._nextHigherCount;
  }
  else
    return 0;
}

char*             DB::getTool(char* name){
  int i=findName(name);      
  if(i >=0 )
    return _data[i]._tool;
  else
    return NULL;
}
//
/** PRIVATE **/
//
int            DB::findName(char* name){
  for(int i=0;i<_size;i++){
    if(!strcmp(_data[i]._name,name))
      return i;
  }
  return -1;
}


0
 
micahAuthor Commented:
char*[] ? not sure I understand you there.  Here is my code


what does it take to pass back _nextHigher?  Once it is passed back how do I print out each element. When I pass it back now it seems to get stomped.  






#ifndef __DB
#define __DB

#include "Device.h"
//
// a realy crappy database
//

struct dbStruct{
  char        _name[50];
  DEVICETYPE  _deviceType;
  char **     _nextHigher;
  int         _nextHigherCount;
  char        _tool[50];

};

class DB{
 public:
  DB();
  ~DB();
  DEVICETYPE getDeviceType(char* name);

  int getNextHigher(char* name,char** data);

  char* getTool(char* name);

 private:
  int findName(char* name);
  dbStruct _data[30];
  int _size;
};
#endif

#include "DB.h"
#include <string.h>

DB::DB(){

  for(int i=0;i<30;i++){
    _data[i]._nextHigher = new char*[5];      
    for(int j=0;j<5;j++)
      _data[i]._nextHigher[j]=new char[50];
  }      
  strcpy(_data[0]._name,"panel");      
  _data[0]._deviceType = PANEL;
  strcpy(_data[0]._nextHigher[0],"fastener_p");
  _data[0]._nextHigherCount=1;
  strcpy(_data[0]._tool,"NULL");

  strcpy(_data[1]._name,"ratchet");                  
  _data[1]._deviceType = ROTATIONAL_TOOL;
  strcpy(_data[1]._nextHigher[0],"NULL");
  _data[1]._nextHigherCount=0;
  strcpy(_data[1]._tool,"NULL");

  strcpy(_data[2]._name,"fastener_p");                  
  _data[2]._deviceType = FASTENER;
  strcpy(_data[2]._nextHigher[0],"NULL");
  _data[2]._nextHigherCount=0;      
  strcpy(_data[2]._tool,"ratchet");

  strcpy(_data[3]._name,"LRU");                  
  _data[3]._deviceType = GENERIC;
  strcpy(_data[3]._nextHigher[0],"fastener_p");
  strcpy(_data[3]._nextHigher[1],"harness_p");
  _data[3]._nextHigherCount=2;      
  strcpy(_data[3]._tool,"NULL");

  strcpy(_data[4]._name,"harness_p");                  
  _data[4]._deviceType = HARNESS;
  strcpy(_data[4]._nextHigher[0],"NULL");
  _data[4]._nextHigherCount=0;      
  strcpy(_data[4]._tool,"NULL");  
 
 _size = 5;
}


DB::~DB(){
  for(int i=0;i<30;i++){
    for(int j=0;j<5;j++)
      delete [] _data[i]._nextHigher[j];
    delete [] _data[i]._nextHigher;
  }      
}

DEVICETYPE        DB::getDeviceType(char* name){
  int i=findName(name);
  if( i >=0 )
      return _data[i]._deviceType;
    return INVALID;
 
}
 

int             DB::getNextHigher(char* name,char** data)
{
  int i=findName(name);
  if(i >=0 ){
    data = &_data[i]._nextHigher;
    return _data[i]._nextHigherCount;
  }
  else
    return 0;
}

char*             DB::getTool(char* name){
  int i=findName(name);      
  if(i >=0 )
    return _data[i]._tool;
  else
    return NULL;
}
//
/** PRIVATE **/
//
int            DB::findName(char* name){
  for(int i=0;i<_size;i++){
    if(!strcmp(_data[i]._name,name))
      return i;
  }
  return -1;
}


0
 
nietodCommented:
Change GetNextHigher to to take a "char ** &"  That i, it takes a parameter that it can alter (that is what the & is for) and that parameter is a pointer to a pointer to characters.

int DB::getNextHigher(char* name,char** &data)
      {
        int i=findName(name);
        if(i >=0 ){
          data = _data[i]._nextHigher;
          return _data[i]._nextHigherCount;
        }
        else
          return 0;
      }
0
 
nietodCommented:
I don't see a place where you are using this procedure, so I'll make one up.

char **StrAry;
int StrCnt = SomeDB.getNextHigher("Searchforme",StrAry);

for (int i = 0; i < StrCnt; ++i)
   cout << *StrAry++;

let me know if you have any questions.  I have not answered because ecw was here first and I believe could have provided the same information.

FYI   you may want to add the "const" declaration to your char * parameters that are treated as constant, for example, the first parameter to getNextHigher.
0
 
micahAuthor Commented:
This is how I want to call getNextHigher, what do I need to do to have junk point to the contents of _nextHigher in the struct in DB.

How do I get the following to work

#include "DB.h"
#include "iostream.h"
void main(){
  DB db;
  char** junk;
  int junkCount;
  junkCount=db.getNextHigher("panel",&junk);
  cout<<junk[0]<<endl;
}
0
 
nietodCommented:
That is exactly what I showed, you except I passed the parameter (junk) by reference so an  wasn't needed, that is my way you specify

 junkCount=db.getNextHigher("panel",junk);  // no &

instead of

 junkCount=db.getNextHigher("panel",&junk); // with &

If you want the &, then the GetNextHigher function should take a pointer to a char **, rather than a reference to a char **.  That is it should take "char ***", rather thann "char ** &"  In that case it would be

int DB::getNextHigher(char* name,char*** data)
{
        int i=findName(name);
        if(i >=0 ){
             data = &_data[i]._nextHigher;
             return _data[i]._nextHigherCount;
         }
         else
                return 0;
 }


0
 
Answers2000Commented:
Maybe this is way out in left field,

 but why not pass back either a point to the structure or an array/vector of strings (or reference/pointer to one)


0
 
nietodCommented:
Don't you think the question was already answered?  I choose not to answer because ecw really deserved it, he was here first and suplied the correct answer.  I oftered additional help if additional information was supplied and gave it.  
0
 
micahAuthor Commented:
The comments where very good, the final proposed answer which came after the comments was a 'C'
0
 
nietodCommented:
micah, you can choose who gets the grade.  In the future, if you don't like the submitted answer, you can reject it and ask another expert to submit a "dummy" answer.  Keeping the system fair will help to keep it running.  I know of at least two experts who left (and whose contributions are sorely lost) because other experts were "stealing" their points.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.