tags:

views:

116

answers:

5

I have a class definition of the form

class X
{
  public:
     //class functions
  private:
      A_type *A;
      //other class variables
};

and struct A_type is defined as

struct A_type
{ 
  string s1,s2,s3;
};

Inside the constructor, I allocate appropriate memory for A and try A[0].s1="somestring"; It shows segmentation fault. Is this kind of declaration invalid, or am I missing something

Edit: New code from OP moved from a comment [neilb]

#include <stdio.h> 
#include <math.h> 
#include <string> 
#include <iostream> 
using namespace std; 

struct HMMStruct { string a; }; 

HMMStruct *HMMs; 

int main() { 
    HMMs=(HMMStruct*)malloc(sizeof(HMMStruct)*2); 
    HMMs[0].a="sdfasasdsdfg"; 
    cout << HMMs[0].a << endl; 
} 
+1  A: 

What do you mean by 'allocate memory'? You have to say, 'new A_type'. If you just call malloc, the constructors won't run, and the assignment won't work.

bmargulies
Thanks for the pointers! Done with changing all the mallocs to news in some 1200 lines of code and it works just fine :-)
Balakrishnan
+3  A: 

Why not:

class X
{
  public:
     //class functions
  private:
      A_type a;
};

In other words, why dynamically allocate the A_type instance?

Edit: The problem with the new code you posted, is that it uses malloc(). If you use malloc() constructors will not be called which is essential for non-POD types like strings. You should not be using malloc in a C++ program - everything should be allocated using new, which will call constructors correctly:

HMMs= new HMMStruct[2]; 

And your code doesn't really work with char * members - it just doesn't fail so obviously.

anon
He's trying to access `A` as an array, notice the `A[0].s1 = ...`
Thorarin
@Thorarin OK, well in that case why not a vector of A_type?
anon
Beats me, but my C++ is very rusty :)
Thorarin
I just figured out a solution. It works when I use char* instead of string. But I dont know why. Any pointers?
Balakrishnan
@Balakrishnan Not unless you post more code that illustrates your problem, particularly how you are allocating things.
anon
Ok, after some analysis I simplified the problem. The problem is not with allocating memory or defining a struct inside a class. The problem was with defining a member of type string inside a struct.Here is a code that fails#include <stdio.h>#include <math.h>#include <string>#include <iostream>using namespace std;struct HMMStruct{ string a;};HMMStruct *HMMs;int main(){ HMMs=(HMMStruct*)malloc(sizeof(HMMStruct)*2); HMMs[0].a="sdfasasdsdfg"; cout << HMMs[0].a << endl;}
Balakrishnan
@Balakrishnan You should post new information by editing your original question. I've done this for you in this (one-time only) case.
anon
Sorry, did'nt know about that. Thanks!
Balakrishnan
+1  A: 

Inside the constructor, I allocate appropriate memory for A and try A[0].s1="somestring"; It shows segmentation fault. Is this kind of declaration invalid, or am I missing something

Your bug is probably in the code you didn't post which is in the allocation of your memory for A.

Or perhaps you have more than 1 constructor and you aren't allocating the memory in one of the constructors.

Brian R. Bondy
A: 

Since you're C++'ing it, use a std::vector instead of an array. Then the problem disappears by itself. Something in the lines of:

#include <vector>
#include <string>
using std::string;
using std::vector;

struct A_type
{
    string s1,s2,s3;
    A_type(string str1,string str2, string str3): s1(str1), s2(str2), s3(str3) {};
};
class X
{
public:
    X();
private:
    vector<A_type> A;
};
X::X()
:   A(vector<A_type>())
{
    A.push_back(A_type("something","or","other"));
    //...
    // Access vector items by A[index] or better A.at(index)
}

Would be better C++ IMHO.

rubenvb
A: 

The problem is that you are using malloc instead of new. Malloc just allocates raw bytes, new allocates memory for an object, and calls the constructor for that object. Essentially you are left with a class/struct with uninitialized values. In your case the string has not been initialized so trying to use it causes a seg fault. Here's what you want:

#include <stdio.h> 
#include <math.h> 
#include <string> 
#include <iostream> 
using namespace std; 

struct HMMStruct { string a; }; 

HMMStruct *HMMs; 

int main() { 
    HMMs = new HMMStruct[2];
    HMMs[0].a="sdfasasdsdfg"; 
    cout << HMMs[0].a << endl; 
    delete [] HMMs; // don't forget to delete.
} 
Niki Yoshiuchi