LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
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 07-22-2007, 07:27 AM   #1
mesh2005
Member
 
Registered: Sep 2005
Location: Ägypten
Distribution: Ubuntu 5.10
Posts: 155

Rep: Reputation: 30
Unhappy What is wrong with my code? C++ and segmentation fault


I'm trying to allocate an array of pointers dynamically. The array is allocated successfully in the routine "allocSpace" but when it returns to the main functions it is no longer available, it gives me 'Segmentation Fault'. Please help.

Code:
#include <iostream>
using namespace std;

typedef struct {
 char* name;   /* '\0'-terminated C string */
 int   num;
} SomeStruct;

void allocSpace(SomeStruct **);

int main ()
{

  SomeStruct **arr;
  allocSpace(arr);  
  for (int i=0;i<5;i++)
    cout<<arr[i]->num;
  return 0;
}

void allocSpace(SomeStruct **x)
{  
  x = (SomeStruct**) malloc(sizeof(SomeStruct *) * 5);
  for (int i=0 ; i<5 ; i++)
  {
        x[i] =  new SomeStruct;
        x[i]->num = i;
        cout<<x[i]->num;
  }  
}

Last edited by mesh2005; 07-22-2007 at 07:40 AM.
 
Old 07-22-2007, 08:51 AM   #2
ineya
Member
 
Registered: Jul 2007
Posts: 39

Rep: Reputation: 16
arr is passed by value.

you can fix by adding reference (little confusing when near stars) or by adding one more star :-)

Code:
#include <iostream>
using namespace std;

typedef struct {
 char* name;   /* '\0'-terminated C string */
 int   num;
} SomeStruct;

void allocSpace(SomeStruct ***);

int main ()
{

  SomeStruct **arr;
  allocSpace(&arr);  
  for (int i=0;i<5;i++)
    cout<<arr[i]->num;
  return 0;
}

void allocSpace(SomeStruct ***x)
{  
  *x = (SomeStruct**) malloc(sizeof(SomeStruct *) * 5);
  for (int i=0 ; i<5 ; i++)
  {
        (*x)[i] =  new SomeStruct;
        (*x)[i]->num = i;
        cout<<(*x)[i]->num;
  }  
}
I also suggest using some typedefs.
 
Old 07-22-2007, 09:02 AM   #3
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
When you call allocSpace(), parameter x is a local copy (within allocspace()) of variable arr in function main(). allocspace() alters that local copy when it does a malloc(). Variable arr in main() is never actually set or altered by your program.

You want arr to be an array of pointers to structs, with the array dynamically allocated with malloc() and the pointers dynamically allocated with new, right?

I present two solutions: an adequate one, and a better one.

The adequate one:

Code:
#include <iostream>
using namespace std;

typedef struct {
 char* name;   /* '\0'-terminated C string */
 int   num;
} SomeStruct;

void allocSpace(SomeStruct ***);

int main ()
{

  SomeStruct **arr;
  allocSpace(&arr);  
  for (int i=0;i<5;i++)
    cout<<arr[i]->num;
  return 0;
}

void allocSpace(SomeStruct ***x)
{  
  *x = (SomeStruct**) malloc(sizeof(SomeStruct *) * 5);
  for (int i=0 ; i<5 ; i++)
  {
        (*x)[i] =  new SomeStruct;
        (*x)[i]->num = i;
        cout<<(*x)[i]->num;
  }  
}
I think of this one as better for stylistic reasons:

Code:
#include <iostream>
using namespace std;

typedef struct {
 char* name;   /* '\0'-terminated C string */
 int   num;
} SomeStruct;

SomeStruct **allocSpace(void);

int main ()
{

  SomeStruct **arr;
  arr=allocSpace();
  for (int i=0;i<5;i++)
    cout<<arr[i]->num;
  return 0;
}

SomeStruct **allocSpace(void)
{  
  SomeStruct **result;

  result = (SomeStruct**) malloc(sizeof(SomeStruct *) * 5);
  for (int i=0 ; i<5 ; i++)
  {
        result[i] =  new SomeStruct;
        result[i]->num = i;
        cout<<result[i]->num;
  }  

  return result;
}
To make the code even simpler, consider the possiblity of allocating an array of SomeStruct directly, rather than allocating an array of individual pointers to SomeStruct.

Hope this helps.
 
Old 07-22-2007, 12:33 PM   #4
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
I think you should decide if you want to learn C or C++. Your program, while it may compile as C++ code (it won't compile as C), is horrible mish-mash of both. A good C++ programmer knows where C and C++ differs and can handle raw arrays with confidence, but a good C++ programmer also puts what C++ offers to use too. And when you start learning C++, you should use std::string and std::vector, for example, from the start. These things were incorporated into C++ to assist the programmer and if you master the c++ standard library you've come far into the language.
 
Old 07-23-2007, 07:37 AM   #5
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
Quoth hivemind:
Quote:
I think you should decide if you want to learn C or C++.
An excellent viewpoint, valid for many. It doesn't necessarily apply to everyone.

I use C mostly. C++'s fine additions can be used for a complete paradigm shift, as hivemind suggests. But they can also be used piecemeal in what would otherwise be a C program. That's the way I use C++.

I'm sure I'm passing up many aids to productivity by using C++ in such an ugly manner, but my method works for me, quickly and easily.

Be a purist if you want. That has many rewards, many of which are quite practical.

Or just grab those elements of C++ which float your boat, and go with it.
 
Old 07-23-2007, 09:14 AM   #6
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Unless you know what your doing and anybody using your code knows what they are doing do not mix malloc and new calls, they are not the same yet this instance makes no difference besides when freeing memory.

Personally I would have wrote it like so:
Code:
#include <iostream>
#include <string>
#include <vector>


struct SomeStruct
{
explict SomeStruct(int const& number):m_number(number){}
SomeStruct(SomeStruct const& rhs):m_number(rhs.m_number),m_name(rhs.m_name){}
SomeStruct& operator=(SomeStruct const& rhs)
{
	m_number = rhs.m_number;
	m_name = rhs.m_name;
	return *this;
}
 int   m_number;
 std::string m_name;
};

typedef std::vector<SomeStruct>::iterator iter;


int main ()
{

std::vector<SomeStruct> arr;
//construct the objects
  for (int i=0 ; i<5 ; ++i)arr.push_back( SomeStruct(i) );
//print the values
  for (iter i=arr.begin() ;i != arr.end();++i)std::cout <<i->m_number <<std::endl;
}
 
Old 07-23-2007, 10:33 AM   #7
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
Quoth dmail:
Quote:
Unless you know what your doing and anybody using your code knows what they are doing do not mix malloc and new calls
This is a good rule, but it is not as restrictive as it sounds. If:
  1. neither you nor anybody maintaining your code follows a malloc()/realloc() by a delete or delete[] of the same object, and
  2. neither you nor anybody maintaining your code follows a new with a free() of the same object,
then you can be considered to be "knowing what you are doing".
 
Old 07-23-2007, 10:53 AM   #8
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
This is a good rule, but it is not as restrictive as it sounds. If:...then you can be considered to be "knowing what you are doing".
This is untrue, as I have said new and malloc are not the same; if you know the differences and hide them then you can be considered to know what you are doing. There should be a very very good reason to use malloc in C++ if there is not then problems will follow.

Last edited by dmail; 07-23-2007 at 10:55 AM.
 
Old 07-23-2007, 03:48 PM   #9
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
malloc doesn't know about constructors, it allocates raw memory. If you're programming in C++ you use new and delete, if you program in C you use malloc (and its friends) and free.

This usenet post sums it up quite nicely:
Quote:
Reasons to always use new:

1. Somewhat friendlier syntax, as malloc() requires a cast unless the
results are assigned to a void*, and you usually do some arithmetic in
the size calculation. Examples:

int* arr = static_cast<int*>(malloc(5 * sizeof *arr));

int* arr = new int[5];

2. It gives a more consistent allocating scheme, so that you don't have
a mix of new and malloc(). Of course, one of the pitfalls of C++ is the
difference between new and new[], requiring delete or delete[]. There
is only one deallocation for malloc().

3. If you change your mind on a previously POD-type struct, you won't
have to find and change the malloc() calls.

Last edited by Hivemind; 07-23-2007 at 03:51 PM.
 
Old 07-24-2007, 08:55 PM   #10
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: LFS-Version SVN-20091202, Arch 2009.08
Posts: 1,496

Rep: Reputation: 68
Quote:
malloc() requires a cast unless the results are assigned to a void*

This is actually incorrect.


void pointers can become any kind of pointer. But I do agree that you should use new instead of malloc in C++
 
Old 07-25-2007, 05:55 AM   #11
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by exvor
This is actually incorrect. ...
You are correct for C yet not C++.
http://www.research.att.com/~bs/bs_faq2.html#void-ptr
 
Old 07-25-2007, 06:32 AM   #12
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
dmail beat me to it. This is one of the cases where C and C++ differs. In C++, there are no implicit conversions from pointer-to-void to, say, pointer-to-char, a cast is required. In C it's not only unnecessary to cast what malloc returns it's bad because it can mask a failure to include its header. Anyway, this has been covered so many times and is getting a bit off-topic for the thread.
 
Old 07-25-2007, 03:42 PM   #13
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: LFS-Version SVN-20091202, Arch 2009.08
Posts: 1,496

Rep: Reputation: 68
Silly C++

Yeah it is getting off topic sorry :P
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
simple c code but whenever running getting segmentation fault with getch() invincible.rish Linux - General 1 01-26-2007 07:55 AM
when code tries to execute at that time i am getting segmentation fault dayalan_cse Programming 1 12-17-2006 11:30 AM
fsck fails. Code: Bad EIP value. Segmentation fault. MOHCTP Debian 4 09-07-2005 09:35 PM
dpkg returned an error code (1) Segmentation fault questionman Debian 6 11-02-2004 01:04 AM
segmentation fault in following peice of code :please help linorg Programming 2 03-18-2004 09:57 PM


All times are GMT -5. The time now is 11:39 AM.

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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration