tags:

views:

133

answers:

3

Hi,

Based on your comments, let me modified the original question...

I want to create a struct with size of 4kb (this size is a requirement so I have to meet it). The problem was that I couldn't modify the value of the string variable contained in the struct because the compiler throws a segmentation fault. Currently, if I use a pointer to string instead of a string variable, I now know how to do it (thanks to you guys), however, I read that the way that I'm using to allocate the 4kb of memory (malloc) is not the best or the appropriate. If I use the "new" keyword, it dynamically allocates enough memory for the struct and it probably uses a different value than 4kb, right? and this is what I don't want.

I still have the doubt about why I could not modify the value of a string variable (not pointer) contained in my struct (something like paginas -> dato = "test"). It probably should be a consequence of the use of malloc

Anyway, I would really appreciate your advices about how to allocate the 4kb of memory.

The original code in c++ is the following:

#define TAM 4000
#define NUMPAGS 512

struct pagina 
{
   bitset<12> direccion; 
   char operacion; 
   char permiso;
   string *dato; //I prefer to have a string variable
   int numero;
}; 

void crearPagina(pagina* pag[], int pos, int dir) 
{
 pagina * paginas = (pagina*)malloc(sizeof(char) * TAM); 
 paginas -> direccion = bitset<12> (dir);
 paginas -> operacion = 'n';
 paginas -> permiso = 'n'; 
 string **tempDato = &paginas -> dato;
 char *temp = " ";
 **tempDato = temp;
 paginas -> numero = 0;
 pag[pos] = paginas;  
}

Thanks in advance!!!

+5  A: 

dato is a pointer to a string. That is, it tells you where to look for the string, but it doesn't actually contain the string.

So if you wish to assign a string to it, you must allocate the memory to hold the string yourself, and give the pointer to that memory to the struct to hold for you.

pagina->dato = new string("test");

When you are finished with the struct, you will need to remember to release the memory for the string or you will get a "memory leak" (because, again, the struct is not responsible for the memory containing the string, only for remembering where you put it):

delete pagina->dato;
pagina->data = NULL;
Jason Williams
Thanks for your help!!! One more question: In case I decide to change the pointer to string to string (string *dato to string dato), how would I modified the value? because using pagina -> dato = "test" will give me a segmentation fault, right?
Eric
No, if it is a string, then pagina->dato will be an actual object embedded in the struct, not just a pointer-to-an-object. So dato="test" will then ask the string object to copy "test" into itself, which should work ok if the string class is properly implemented. (You also will not need to delete the dato when you are finished with it, as it is "part of" the struct rather than an external object)
Jason Williams
that is weird. Having the same code except for the line "string dato", if I write paginas->dato="test"; in the struct and then I run the program, a segmentation fault is shown, any idea?
Eric
@Eric: Yes. You're using `malloc()` for an object with user-defined objects (aka instances of classes). That's bound to crash. Use `new` to allocate objects on the heap. That makes sure constructors are called. Or get rid of manual dynamic allocation altogether as shown in my reply.
sbi
A: 
struct pagina 
{
   bitset<12> direccion; 
   char operacion; 
   char permiso;
   std::string dato;
   int numero;
   pagina(int dir)
     : direccion(dir), operation('n'), permiso('n'), dato(" "), numero()
   {
   }
};

void crearPagina(std::vector<pagina>& pag, int dir) 
{
    pag.push_back(pagina(dir));
}
sbi
thanks for your help!
Eric
+1  A: 
struct pagina 
{
   pagina(int dir)
         : direccion(dir)
         , operacion('n')
         , permiso('n')
         , dato(" ")
         , numero(0) {}

   bitset<12>  direccion; 
   char        operacion; 
   char        permiso;
   std::string dato;
   int         numero;
};

void createPagina(pagina* pag[], int pos, int dir) {
    pag[pos] = new pagina(dir);
}

This is more C++ (as oppose to C) way of doing what you want. Create a constructor instead of creation procedure and use new instead of malloc. Also I would advice using std::vector<pagina> instead of raw pointer array.

sfider
Is there a way to specify the size of the memory block that will be assigned using the "new" keyword? The idea of using malloc is to create a memory block of 4 KB.
Eric
Why do you want to allocate a specific amount of memory instead of allocating the memory needed to hold the object? `new` will allocate at least as many bytes as necessary _and call the object's constructor_.
sbi
@sbi Because it is a specific requirement. I need to create a structure of 4 kb and the only way that I know to meet this requirement is to use malloc. Do you have any suggestion? :)
Eric
new is for creating objects or array of objects. It makes sure that object or array gets memory it needs and that all constructors are called. If you want to allocate 4kb memory (raw memory I assume) you can allocate array of char like this: new char[4096]
sfider
@Eric: Why do you want to allocate 4kb of storage and why do you want to put this structure into it? I'm sorry to say, but your code is mostly complete nonsense (see my comments to your question) and it's more or less impossible to draw meaningful conclusions about your requirements from it. (I suppose this is the reason so few people answered at all.) I suggest you go and modify your question so that it actually states your requirements, so that we would be able to suggest how to achieve them.
sbi