In openCV code sapmles in it's document, I saw they simply pass the Mat as a refrence and fill it.But I have a problem in my code. when i call TestMethod, it doese not fill them.
void TestMethod(Mat a, Mat b)
{
a = imread("img1.jpg");
b = imread("img2.jpg");
return;
}
You might be confused by how OpenCV uses typedefs to hide reference types. I would lookup how typedefs like InputArray are defined, you'll see they have an & in them to make them reference types. cv::Mat is not a typedef so you need to declare it as a reference in the function's argument list.
void TestMethod(Mat& a, Mat& b)
{
a = imread("img1.jpg");
b = imread("img2.jpg");
return;
}
The way you have it written now, a and b are copies of the Mat variables you passed when you called the function. You are just overwriting copies that are deallocating when the function returns.
Related
I have a class with an Armadillo vector as an instance variable. I know that I can create an Armadillo vector using a memory location as a constructor argument. However, I don't see a way to set the vector memory after the vector has been created.
I need to do this because the memory address for the vector is passed as constructor to the class. It would be nice to be able to do something like:
Class foo {
arma::Row<float> myVec;
foo(float *memptr, int size)
{
myVec.set_mem(memptr, size);
}
};
This approach may work. First construct a temporary vector from the provided memptr. Then move the temporary vector to myVec using std::move(). This will also cause the temporary vector to become invalid.
Class foo {
arma::Row<float> myVec;
foo(float *memptr, int size)
{
arma::Row<float> temp(memptr, size, false, false);
myVec = std::move(temp);
}
}
Keep in mind that memptr has to point to valid memory for the lifetime of the foo object. If that cannot be guaranteed, change the constructor of temp so it copies the memory.
arma::Row<float> temp(memptr, size, true, false);
Excerpt from Huon Wilson's Finding Closure in Rust:
Capturing entirely by value is also strictly more general than capturing by reference: the reference types are first-class in Rust, so "capture by reference" is the same as "capture a reference by value". Thus, unlike C++, there’s little fundamental distinction between capture by reference and by value, and the analysis Rust does is not actually necessary: it just makes programmers’ lives easier.
I struggle to wrap my head around this. If you capture a reference "by value", don't you capture the data that is stored on the heap? Or does it refer to the pointer value of the reference, which is found on the stack?
I think the article means to say that the effect is almost equivalent. Immutable references implement Copy trait because of which when you capture a reference by value, it is copied. So basically you just created one more shared reference to the same data.
fn as_ref(_x: &String) {}
fn as_mut(_x: &mut String) {}
fn main() {
let mut x = String::from("hello world");
let y = &x;
let _ = move || {
as_ref(y); // here you moved y but it
// basically created a copy
};
let z = y; // can be used later
// The same cannot be done by mutable
// refs because they don't
// implement Copy trait
let y = &mut x;
let _ = move || {
as_mut(y); // here you moved y and
// it cannot be used outside
};
// ERROR! Cannot be used again
//let z = y;
}
Playground
Or does it refer to the pointer value of the reference, which is found on the stack?
Yes, ish.
In Rust, references are reified, they're an actual thing you manipulate. So when you capture a reference by value, you're capturing the reference itself (the pointer, which is what a Rust reference really is), not the referee (the pointee).
Capturing by reference basically just implicitly creates a reference and captures it by value.
In C, we could do the following to create a 2D array:
int intArray[10][10];
In C99, we could create a VLA:
size_t col = 10;
size_t row = 10;
int array[row][col];
Within a method in Objective-C, I can create a 2D array that hold ids as follows:
id genObjectArray[10][10];
Is it possible to create an 2d array ivar in Objective-C?
The following is what I have tried:
#interface myClass ()
{
id objArray[][];
//This doesn't work, unless I specific size.
//I want to do this, so that I could specific the size later during
//runtime
}
In C, I could do the following and allocate space for a 2D array later within a block scope:
int **array;
int *elements;
I can do the same within Objective-C, too, but the problem arises when I use id or other object types; other words, the following is not valid:
id **array;
id *elements;
Thus, my question is, is it possible to declare a C-style 2D array as ivar that holds ids?
I understand that we could achieve that using normal NS(Mutable)Array; but this just serves for educational purposes.
You can't do this. For a C99 VLA, the space required for the array is allocated at the point the array is declared. For an ivar, the analogous time to do that would be when the object was allocated and initialized, but there's no support in Objective C to do that. You'd need to have a stronger definition of what an object constructor can do (more like Java's constructors than Objective C's initializers).
The closest you can get would be something like this:
#interface myClass () {
id * objArray;
}
-(instancetype)initWithRow:(size_t)row col:(size_t)col {
self = [super init];
if (self) {
objArray = calloc(row * col * sizeof(id));
}
return self;
}
-(void)dealloc {
free(objArray);
}
In that case, you're declaring the ivar as a pointer and managing the storage yourself (and the stride, for a multi-dimensional array).
Obviously, NSArray is better in all possible ways.
I am working on a chess engine in C/Objective-C and I rewrote a large part of my engine in straight-c to improve the speed. My question is, I have about 3KB of tables I initialize in my C file that I don't want to reinitialize every time a function from this file is called. If this were a regular objective-c class I would create a shared instance. However, the core of my engine is in two .h and a .c files. Should I make all of the tables used by my engine static? Will they persist between multiple other files calling functions in my engine? Should I make a static struct to hold my tables? I'm not sure what the best approach is here. Thanks!
Example:
Test.h:
int getInt(int index);
Test.c:
static int integers[4] = {1,2,3,4};
int getInt(int index) { return integers[index]; }
Every time I call getInt from another file, will it reallocate 'integers'? Or will it reuse the same array? I want to prevent it from unnecessarily reallocating a bunch of static arrays.
Ok, what you did was accessor on a static variable...
A static is only initialized once, so it does get initialized only once per launch.
You can keep it this way, or change it to a global to access it without calling function.
This code could typically get inlined, so changing it to a global is more a matter of taste than performances.
Edit: short summary on allocations
static int array[] = {1, 2}; // Allocated and initialized once
int array2[] = {1, 2, 3}; // Allocated and initialized once
int function() {
int array3[] = {1, 2, 3}; // Allocated and initialized at every call of function();
static int *array4 = malloc(42); // Allocated and initialized once
int *toto = malloc(42); // Allocated at every call of function();
}
For some reason I just cant seem to get my head around the process of creating a C-Array instance variable for a class that can have elements added to it dynamically at runtime.
My goal is to create a class called AEMesh. All AEMesh objects will have a c-array storing the vertexdata for that specific AEMesh's 3D model for use with OpenGL ES (more specifically it's functionality for drawing a model by passing it a simple C-Array of vertexdata).
Initially I was using an NSMutableArray, on the assumption that I could simply pass this array to OpenGL ES, however that isnt the case as the framework requires a C-Array. I got around the issue by essentially creating a C-Array of all of the vertexdata for the current AEMesh when it came time to render that specific mesh, and passing that array to OpenGL ES. Obviously the issue here is performance as I am constantly allocating and deallocating enough memory to hold every 3D model's vertexdata in the app about a dozen times a second.
So, Im not one to want the answer spoon fed to me, but if anyone would be willing to explain to me the standard idiom for giving a class a mutable c-array (some articles Ive read mention using malloc?) I would greatly appreciate it. From the information Ive gathered, using malloc might work, but this isn't creating a standard c-array I can pass in to OpenGL ES, instead its more of a pseudo-c-array that works like a c-array?
Anyways, I will continue to experiment and search the internet but again, if anyone can offer a helping hand I would greatly appreciate it.
Thanks,
- Adam Eisfeld
The idea would just be to add a pointer to an array of AEMesh structures to your class, and then maintain the array as necessary. Following is a little (untested) code that uses malloc() to create such an array and realloc() to resize it. I'm growing the array 10 meshes at a time:
#interface MyClass : NSObject
{
int meshCount;
AEMesh *meshes;
}
#end
#implementation MyClass
-(id)init {
if ((self = [super init])) {
meshCount = 0;
meshes = malloc(sizeof(AEMesh)*10);
}
return self;
}
-(void)addMesh:(AEMesh)mesh {
if (meshCount % 10 = 0) {
meshCount = realloc(sizeof(AEMesh) * (meshCount + 10));
}
if (meshCount != nil) {
meshes[meshCount] = mesh;
meshCount++;
}
}
#end
It might be worthwhile to factor the array management into it's own Objective-C class, much as Brian Coleman's answer uses std::vector to manage the meshes. That way, you could use it for C arrays of any type, not just AEMesh.
From the information Ive gathered, using malloc might work, but this
isn't creating a standard c-array I can pass in to OpenGL ES, instead
its more of a pseudo-c-array that works like a c-array?
A C array is nothing more than a series of objects ("objects" used here in the C sense of contiguous memory, not the OO sense) in memory. You can create one by declaring it on the stack:
int foo[10]; // array of 10 ints
or dynamically on the heap:
int foo[] = malloc(sizeof(int)*10); // array of 10 ints, not on the stack
int *bar = malloc(sizeof(int)*10); // another way to write the same thing
Don't forget to use free() to deallocate any blocks of memory you've created with malloc(), realloc(), calloc(), etc. when you're done with them.
I know it doesn't directly answer your question, but an even easier approach would be to work with an NSMutableArray instance variable until the point where you need to pass it to the API, where you would use getObjects:range: in order to convert it to a C-Array. That way you won't have to deal with "mutable" C-Arrays and save yourself the trouble.
If you're willing to use ObjectiveC++ and stray outside the bounds of C and ObjectiveC, then you can use a std::vector to amortise the cost of resizing the array of vertex data. Here's what things would look like:
include <vector>
include <gl.h>
#interface MyClass {
std::vector<GLfloat> vertexData;
}
-(void) createMyVertexData;
-(void) useMyVertexData;
#end
#implementation
-(void) createMyVertexData {
// Erase all current data from vertexData
vertexData.erase(vertexData.begin(),
std::remove(vertexData.begin(),
vertexData.end());
// The number of vertices in a triangle
std::size_t nVertices = 3;
// The number of coordinates required to specify a vertex (x, y, z)
std::size_t nDimensions = 3;
// Reserve sufficient capacity to store the vertex data
vertexData.reserve(nVertices * nDimensions);
// Add the vertex data to the vector
// First vertex
vertexData.push_back(0);
vertexData.push_back(0);
vertexData.push_back(0);
// And so on
}
-(void) useMyVertexData {
// Get a pointer to the first element in the vertex data array
GLfloat* rawVertexData = &vertexData[0];
// Get the size of the vertex data
std::size_t sizeVertexData = vertexData.size();
// Use the vertex data
}
#end
The neat bit is that vertexData is automatically destroyed along with the instance of MyClass. You don't have to add anything to the dealloc method in MyClass. Remember to define MyClass in a .mm file