6

I am not very good at C++ and I currently porting some piece of code to C. It allocates a big array of objects like this:

o_list::Node** nodes = (o_list::Node**)malloc(SIZE*sizeof(o_list::Node*)); 

and then fills each position with:

for(int u=0;u<SIZE;u++) nodes[u] = new o_list::Node(); 

From what I understand, the only assurance we have regarding contigous memory is that the pointers to the objects are in fact contiguous, i.e. it might happen that we have:

 _____________________ |x||x||x||x||x||x||x|x| -> contiguous array of pointers; | \ \ | \ \______ | \ \ O O O -> not contiguous positions of objects; 

To correct this, I tried to malloc the first array (of pointers) and then malloc an array of objects, and then assign the pointers to the right positions, like this:

o_list::Node** nodes = (o_list::Node**)malloc(SIZE*sizeof(o_list::Node*)); o_list::Node* contObjs = (o_list::Node*)malloc(SIZE*sizeof(o_list::Node)); for(int u=0;u<SIZE;u++){ contObjs[u] = o_list::Node(); nodes[u] = &contObjs[u]; } 

But this leads to a segmentation fault. I would like to know if my assumption is correct and why I have a segmentation fault in the second option.

Thanks

23
  • 1
    You don't seem to need an array of pointers here. Why not simply allocate an array of objects? Commented Mar 17, 2015 at 11:54
  • 2
    @BaummitAugen I am trying to port this to C... Commented Mar 17, 2015 at 11:57
  • 3
    I find this question a bit unclear. Is it about porting from C++ to C or is it about allocating a contiguous area of memory? Commented Mar 17, 2015 at 12:04
  • 2
    @JeremyP: "Questions seeking debugging help must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it". There's not enough information here to guess what might be wrong with the missing code. The only answerable part of the question ("are arrays contiguous?") is rather trivial. Commented Mar 17, 2015 at 12:48
  • 1
    @JeremyP: I meant trivial compared to the bulk of this question (as well as trivially googlable) - answering just that part, and ignoring the main question, wouldn't be very helpful to anybody. I and others did ask for further info, but it wasn't forthcoming; so I voted to close for the reason I quoted above, which describes the situation exactly. Sorry if you find that snotty, but removing unanswerable questions is how this site maintains its quality. Commented Mar 17, 2015 at 13:05

3 Answers 3

2

You're on the right lines, though getting rid of that first array entirely would be better (if you can). It may involve some design changes elsewhere in your program, so let's leave that for now.

As for your segmentation fault, the only problem I can see is if SIZE is not equal to 300000, you will go out of bounds. Why not use SIZE in the loop?

Sign up to request clarification or add additional context in comments.

2 Comments

Nice catch, but SIZE is indeed = 300000. Sorry. +1 for the catch. Edited.
@a3mlord: Then I'm going to ask you to present a testcase because this is therefore entirely unanswerable. I would also suggest abstracting away the code-porting business as it doesn't seem particularly relevant to your segfault.
2

It is not clear why you need an array of pointers to begin with.

Nevertheless, here are several ways to achieve what you're asking:


o_list::Node objArray[SIZE]; o_list::Node* ptrArray[SIZE]; for (int i=0; i<SIZE; i++) ptrArray[i] = objArray+i; 

o_list::Node* objArray = malloc(SIZE*sizeof(o_list::Node)); o_list::Node* ptrArray[SIZE]; for (int i=0; i<SIZE; i++) ptrArray[i] = objArray+i; 

o_list::Node objArray[SIZE]; o_list::Node** ptrArray = malloc(SIZE*sizeof(o_list::Node*)); for (int i=0; i<SIZE; i++) ptrArray[i] = objArray+i; 

o_list::Node* objArray = malloc(SIZE*sizeof(o_list::Node)); o_list::Node** ptrArray = malloc(SIZE*sizeof(o_list::Node*)); for (int i=0; i<SIZE; i++) ptrArray[i] = objArray+i; 

Comments

0

I'm not an expert on C++ but isn't there an array form of new that will allocate a contiguous array of objects? Something like this?

MyClass * arrayOfMyClass = new MyClass[5]; 

Now you may say "but I'm converting it to C, and C doesn't have new". This is true, but C also doesn't have classes and operator overloading and copy constructors. If you want to use malloc, you need to grasp the nettle and convert your Node class into a C struct. The reason for this is that malloc() is not the C equivalent to new.

new allocated memory and constructs the objects. malloc only allocates memory. You can't even guarantee that the memory it gives you is zero filled. In C you need to provide an initialisation function to do what the constructor would do. The C equivalent of your code would go something like:

void Node_init(struct Node* aNode) { // Any initialisation you need to do of its members } ... struct Node* contObjs = malloc(SIZE * sizeof *contObjs); // or use calloc to get zero filled memory for(int u=0;u<SIZE;u++) { Node_init(&contObjs[u]); // Pass the address of the u'th element } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.