LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-28-2008, 06:18 AM   #1
matiasar
Member
 
Registered: Nov 2006
Location: Argentina
Distribution: Debian
Posts: 321
Blog Entries: 1

Rep: Reputation: 31
C++ dynamic array of struc doubt


I'm studing and making my first real life program in C++. I've got a doubt related with including a string type into a struct when I'm managing memory allocation dynamically.
Bellow I copy the test program I did which works ok. But if I try to use string type instead of "const char *" into the struct I receive a "segment violation" error when I run the program. No error messages when compilling it.

Does anybody knows if I'm doing something wrong?


#include <iostream>
using namespace std;

struct Datos {
const char * fecha;
const char * evento;
};


int main (void)
{
int max = 4;
int n = 0;

Datos * p_Datos = new Datos [4];

while (n < 9)
{
if ( n >= max)
{
max = max + 15;
Datos * p_temp = new Datos [max];

for (int i=0; i <= n; i++)
{
p_temp[i].fecha = p_Datos[i].fecha;
p_temp[i].evento = p_Datos[i].evento;
}
p_Datos = p_temp;
delete [] p_temp;
}

//Asignaciones
p_Datos[n].fecha = "25/11/2008";
p_Datos[n].evento = "Enviar e-mail!!!";
n++;
}

/* Muestra datos */

cout << "\n" << "Fecha\t\t" << "Evento";
for (int i=0; i < n; i++)
{
cout << "\n" << p_Datos[i].fecha << "\t\t" << p_Datos[i].evento;
}
cout << "\n\n";
return 0;
}
 
Old 11-28-2008, 07:52 AM   #2
rizwanrafique
Member
 
Registered: Jul 2006
Distribution: Debian, Ubuntu, openSUSE, CentOS
Posts: 147

Rep: Reputation: 19
I think there are two problems in the program.

You allocate 4 locations to p_Datos using:
Code:
Datos * p_Datos = new Datos [4]
And then try to look to more than 4 using:
[CODE]
for (int i=0; i <= n; i++)
{
...
{/CODE]

Secondly:
Code:
delete [] p_temp;
Will clear up the memory allocated to p_temp even if it has been assigned to another pointer.

Fixing these two things runs the program properly.

My guest is that in const chat * version of the program the point nature of member variables stops memory from being cleared. But that's just a guess. Someone else can give a more definite answer :-)
 
Old 11-28-2008, 08:36 AM   #3
matiasar
Member
 
Registered: Nov 2006
Location: Argentina
Distribution: Debian
Posts: 321

Original Poster
Blog Entries: 1

Rep: Reputation: 31
Thanks for your answer.
I tried the following code, but still I get "segment violation" when using string type into the struct. The same program using const char * works ok...

Code:
#include <iostream>
#include <string>
using namespace std;


struct Datos {
        string fecha;
        string evento;
};



int main (void)
{
        int max = 4;
        int n = 0;

        Datos * p_Datos = new Datos [4];

        while (n < 9)
        {
                if ( n >= max)
                {
                        max = max + 15;
                        Datos * p_temp = new Datos [max];

                        for (int i=0; i < n; i++)
                        {
                                p_temp[i].fecha = p_Datos[i].fecha;
                                p_temp[i].evento = p_Datos[i].evento;
                        }
                        p_Datos = p_temp;
                        delete [] p_temp;
                }

             //Asignaciones
             p_Datos[n].fecha = "25/11/2008";
             p_Datos[n].evento = "Enviar e-mail!!!";
             n++;
        }

        /*  show data */

        cout << "\n" << "Fecha\t\t" << "Evento";
        for (int i=0; i < n; i++)
        {
                cout << "\n" << p_Datos[i].fecha << "\t\t" << p_Datos[i].evento;
        }
        cout << "\n\n";
        return 0;
}
 
Old 11-28-2008, 09:28 AM   #4
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by matiasar View Post
Thanks for your answer.
I tried the following code,
That doesn't look like you did anything to fix the second problem rizwanrafique described.

Quote:
I get "segment violation" when using string type into the struct. The same program using const char * works ok.
The program is not correct even using const char*.
I understand why those serious bugs typically won't result in an immediate crash using const char*, but will using string. However, you are closer than you think to a crash even with the const char * version.

1) What you seem to be doing is inventing your own std::vector. I have done that in many places, because I know how and because I know which situations benefit enough from coding better than std::vector to be worth the trouble. You would be better off just using a std::vector<Datos> instead of reinventing that yourself.

2) If you must write it yourself, you need to be more systematic about the process of switching to the new copy. I suggest:
Code:
                if ( n >= max)
                {
                        int old_max = max;
                        Datos* old_Datos = p_Datos;
                        max = max + 15;
                        p_Datos = new Datos [max];

                        for (int i=0; i < old_max; i++)
                        {
                                p_Datos[i].fecha = old_Datos[i].fecha;
                                p_Datos[i].evento = old_Datos[i].evento;
                        }
                        delete [] old_Datos;
                }
Unlike your version, this one deletes the correct buffer (the old one, not the new one) and this one makes the limit of reading the old buffer explicit rather than relying on the purely single increment growth in n.

But if you want a minimal change, you could just delete the right buffer. Instead of:
Code:
                        p_Datos = p_temp;
                        delete [] p_temp;
use
Code:
                        delete [] p_Datos;
                        p_Datos = p_temp;

Last edited by johnsfine; 11-28-2008 at 09:31 AM.
 
Old 11-28-2008, 12:54 PM   #5
matiasar
Member
 
Registered: Nov 2006
Location: Argentina
Distribution: Debian
Posts: 321

Original Poster
Blog Entries: 1

Rep: Reputation: 31
I understood. Thanks a lot for your help and patience. I finally got it working using your approach Johnsfine.
I'll see if I keep on practicing this issue.

Regards,
Matías
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic Array Sizes JMJ_coder Programming 8 03-05-2008 07:33 PM
list with dynamic array TurtleFace Programming 7 11-05-2006 06:58 PM
expanding dynamic array niteshadw Programming 6 06-25-2005 11:19 PM
More dynamic array problems PTBmilo Programming 5 03-14-2003 12:51 AM
dynamic array in class help PTBmilo Programming 6 03-09-2003 02:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:50 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration