4

I'm translating a part of code from C# to C++.

Here is the point I am :

Class Point
{
    public int X;
    public int Y;
}
const int MAX = 256;

public void ComputePoints(Byte[] image,
                          int width, 
                          int height,
                          out List<Point>[] listPixels)
{
    listPixels = new List<Point>[MAX];

    //etc..
}

(I simplified this piece of code to only show interesting part).

My Question concern the out List<Point>[] listPixels. I've try to translate this by :

public void ComputePoints(unsigned char[] image,
                          int width, 
                          int height,
                          std::vector<Point> *listPixels[])
{
    *listPixels = new std::vector<Point>[MAX];

    //etc..
}

But I have error

Segmentation fault.

How can I write the simplest equivalent to out List<Point>[] listPixels in C++ ?

5
  • I don't see the benefits of using a pointer for your vector. Stick to value semantics when you can. Commented Oct 17, 2017 at 13:42
  • std::vector< std::list< Point> > myVectorOfLists; I would use a vector. Commented Oct 17, 2017 at 13:43
  • I'm confused about the benefit of using an array of List (or std::vector) - why not just have a List<List (or std::vector<std::vector)? Commented Oct 17, 2017 at 13:44
  • @UnholySheep It's an array of list because the array have fixed size (256) and it contains items (List) with variable size. Commented Oct 17, 2017 at 13:50
  • Arrays in C# are much "smarter" than arrays in C++ (they know their size!). Raw arrays and dynamic memory allocation in C++ should generally be avoided and use container classes instead (like std::array, std::vector, etc.). Commented Oct 17, 2017 at 13:51

3 Answers 3

5

Since List<Point>[] is an array of lists, you could use a nested vector (vector of vector) to get the desired behaviour:

std::vector<std::vector<Point> >

Note that it could be important to add a space between the two >'s. Some compilers would not compile without.

Now you are able to pass the vector as reference like

void ComputePoints(... , std::vector<std::vector<Point> > &listPixels)
{
   ...
Sign up to request clarification or add additional context in comments.

2 Comments

"Typically it would not compile without" pretty sure that hasn't been true for quite a while now (unless you are using an outdated compiler)
To compliment this answer, you also don't need to use a pointer as an argument to the function. You can use the address of the variable as function parameter instead of using new inside the function.
1

Why not return vector of vectors by value? In C++11 and newer it's fast and the code is easier to understand.

struct Point {
    int x;
    int y;
};

const int MAX = 256;

std::vector<std::vector<Point>> computePoints(const unsigned char image[], int width, int height) {
    std::vector<std::vector<Point>> points(MAX);
    // Here goes the code that does the calculations and fills 'points'.
    return points;
}

1 Comment

It's a good idea, but I have another function returning bool, so in a case I have to do with equivalent of out
1

For a fixed size array you could use std::array.

You don't need to use new in c++, you can simply use the stack, that's a common problem when transitioning from c#/java to c++.

For simple objects you nearly never need to dynamically allocate them (using new) and if you have to dynamically allocate them don't use raw owning pointers with new, use smart pointers (std::unique_ptr, std::shared_ptr). It's not only the way create objects in c++, allocating objects on stack is also faster than the heap, plus you have better locality.

#include <list>
#incldue <array>

const int MAX = 256;
std::array<std::list<Point>, MAX> array_list;

i also like to type def such long types:

using MyContainer = std::array<std::list<Point>, 256>;
MyContainer array_list;

would be one way to have a array of lists

If you don't necessarily need a list, you could also use a std::vector(which should be your default container), which provides even more locality

For pre - C++11(as you'll find in other answers) you can also use std::vector instead of std::array, which will allocate the items on the heap, but this should be ok, because std::vector provide better functionality compared to plain C arrays.

Or if you really want to use C arrays: Simply on stack:

std::list<Point> my_list_array[MAX];

and the heap allocated version:

std::list<Point>* my_list_array = new std::list<Point>[MAX];
//but don't forget about the delete[]!

4 Comments

He's creating the container specifically to return it outside the function, so it better be created on the heap... And saying to use shared_ptr implies that the object was created on the heap with new or make_shared.
I mean he should't use raw owning pointers. Have to edit my answer. He could still use a stack allocated object, with an in out parameter, if I correctly understand his intentions
I've try to use array but I have a old version of C++, there is some compilation errors.
@A.Pissicat are you using pre - c++11? std::array is available since C++11, if you are using a old compiler you either should consider an update of your compiler(or maybe you already use a modern one and only need to enable c++11), use std::vector as others mentioned or use plain C arrays for fixed sizes. With more info can update my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.