I am working with some C code (not my own) that interfaces with Fortran and insists that all arrays be 1-based. I have a method that returns (a pointer to) an array that I have to line up correctly. The following works:
double* a;
...
a = returnedArray(arraySize);
Now what I need is to get the return to align at a[1], a[2], ... instead. (Of course I could shift things around manually, but there has to be a better way.) I tried to get the compiler to accept
a[1] = returnedArray(arraySize);
*(a+1) = ...
and several other permutations, without success. A web search has not given me anything useful, either.
Try:
`a=returnedArray(arraySize)-1;`
You cannot change that fact that returnedArray() returns a pointer to the first element of your array. And in C arrays, the first element is inevitably index 0.
However, if you offset the pointer by one element before using it, maybe you'll achieve your goal?
double * a;
...
a = returnedArray(arraySize) - 1;
...
double firstValue = a[1];
However, I strongly suggest you stick with index 0 being the first element, and fix the interfacing with Fortran in some other way. Surely, at some point you'll introduce a hard-to-find bug if you keep mixing 0-based and 1-based arrays in your code.
You want to do something like that ?
the array a start at tab[1]
double tab[10];
for(int i = 0 ; i < 10 ; i++){
tab[i] = i;
}
double *a = &tab[1];
for(int i =0 ; i < 9 ; i++){
cout << a[i] << endl;
}
If the memory between Fortran and C is being shared (eg. not copied), you cannot change the indexing of the built-in C type yourself. However, you could make a wrapper for your arrays returned from Fortran, which would make accessing them more convenient, and make it quite clear the difference between 1-indexing and 0-indexing. For example:
class FortranArrayWrapper
{
public:
FortranArrayWrapper(double* a) : A(a) { }
operator double* () const
{
return &A[1];
}
double* A;
};
FortranArrayWrapper a(returnedArray(arraySize));
a[0] = ...; // Index 1 in the array returnedArray, ie. first element in the Fortran array.
a.A[0] = ...; // Actually index '0', unused by Fortran.
Related
I've built a class called IntSet. My problem is that i dont want to storage another element that is the maximum amount of elements i want to introduce in elem array. So, in add method or any other method, i want to find out the max size i've allocated in the IntSet (int dim_max) constructor using this operation :
int n = sizeof(elem) / sizeof(*elem); //or sizeof(elem) / sizeof(int);
cout << "N is = " << n;
However, this doesnt work, everytime n is 1, even if i allocate elem = new int[dim_max];, where dim_max is a variable i read from the keyboard and it's much bigger than 1. Here is the code :
#include <iostream>
using namespace std;
class IntSet{
int *elem;
int dim;
public:
IntSet (int dim_max) {
dim = -1;
elem = new int[dim_max];
}
void add(int new_el) {
int n = sizeof(elem) / sizeof(int);
cout << "N is =" << n;
for(int i = 0; i < n; i++) {
if(elem[i] == new_el) {
cout << "It's already there !";
return;
}
}
dim++;
if(dim == n) {
elem = (int*)realloc(elem, sizeof(int) * (n + 1));
global_var++;
}
elem[dim] = new_el;
}
};
The sizeof operator works on the types at compile time. Since elem is an int*, sizeof(elem) is the same as sizeof(int*). And *elem is an int, so sizeof(*elem) is sizeof(int).
So in the end, your formula is equivalent to sizeof(int*)/sizeof(int), regardless of what you put in elem. There is no standard way to find out the number of elements of the array that that was allocated for a pointer.
For your purpose, you either must either keep track of dim_max in your class, or, better, replace the use of pointers and arrays with the nicer vector.
Vectors offer a size() function, and allow to easily add new element dynamically at the end using push_back(). Maybe it could interest you as well: there is also a set container in the standard library.
elem is a pointer and sizeof(ptr) is always fixed. On 32-bit machine sizeof pointer is 32 bits ( 4 bytes), while on 64 bit machine it's 8 byte. Regardless of what data type they are pointing to, they have fixed size.
So, the computation you are doing sizeof(elem)/sizeof(*elem) will always yield 1 as it's matching with sizeof(int). This would work if elem is an array with predetermined size.
To keep track of current size, you need to have another variable.
Another thing is don't mix new and realloc. Always use new as you are using C++.
It is because, elem is a pointer. So, every time you are doing sizeof(elem) or sizeof(*elem); will give you the size of data type & pointer respectively.
If you havent used dynamic allocation, then answer would be OK.
I would suggest you to use STL container or store max size as a data member.
First thing first you divide two non double value so the result is not what you expect
12/8 is 1.
sizeof a pointer depending on the architecture is 8 or 4.
What you think is sizeof returning the size of array which is only the case for automatic arrays not dynamic ones.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am a C/C++ newbie, so sorry if my question seems straightforward.
It has always been claimed that pointers in C++ are useless. See for example the answer from Konrad Rudolph here https://softwareengineering.stackexchange.com/questions/56935/why-are-pointers-not-recommended-when-coding-with-c
Below I have an example for which I am wondering how can I replace the C code by a C++ code without using any pointers:
double *A;
double **a;
A=new(std::nothrow) double[4];
a=new(std::nothrow) double*[2];
for (unsigned int q=0, k=0; k < 2; k++)
{
a[k]=A + q;
q+=2;
}
delete[] A;
delete[] a;
The programmer codes up as above because he/she needs the pointer a to point to the pointer A so that when modifying the variable to which A points, he/she does not to modify a.
Sometimes, the programmer does a for loop with a[k] from k={0,1,2,3}, and sometimes he does a double for loop a[i][j] from i,j={0,1}.
How can I replace this by a C++ code without using pointers?
Some important clarity: what you're being advised is to not use Raw, Owning Pointers. It's perfectly fine to use Non-Owning Raw Pointers iff you know, as a fact, that you're not responsible for deleteing said memory; or Owning Smart Pointers iff you are responsible for said memory, but deleteing will be handled by the RAII principles of the smart pointer class.
So let's consider what's happening in your code:
A represents ownership over a runtime-sized array of doubles.
a represents ownership over a runtime-sized array of non-owning pointers to doubles, all of which will come from A.
Simply creating an array of objects is either best represented by std::array, for compile-time-sized arrays, or std::vector, for runtime-sized arrays. So we'll need the latter. This is easy to construct:
std::vector<double> A(4);//Array of 4 doubles.
Since a will contain non-owning pointers to A, which we know will outlive a, it's perfectly fine to use raw pointers inside this vector:
std::vector<double*> a(2);
Then, we assign into it, just like your code was already doing:
//Use size_t for sizes in C++. Always, always, always.
for (size_t q = 0, k = 0; k < 2; k++){
a[k] = A + q;//Uh oh, this doesn't compile!
q += 2;
}
Ah, hmm. A isn't a raw pointer anymore. Well, we'll need to use a member function of std::vector to get the raw pointer.
//Use size_t for sizes in C++. Always, always, always.
for (size_t q = 0, k = 0; k < 2; k++){
a[k] = A.data() + q;//There we go.
q += 2;
}
Finally, because our memory is RAII-managed, we don't need to delete this memory afterwards:
//No longer needed
//delete[] A;
//delete[] a;
So the final code will end up looking like this:
std::vector<double> A(4);
std::vector<double*> a(2);
for (size_t q = 0, k = 0; k < 2; k++){
a[k] = A.data() + q;
q += 2;
}
This code is nearly identical to the C-style code you wrote originally, and is much easier to read and maintain. The only difference is the small amount of overhead in std::vector, which the compiler can optimize away for the final program.
If you want code which literally emulates the behavior of your original code, this would be the result. I don't recommend it, because it's more complicated than you need, and limits how the code can be used, but if you just want the direct port (or just want to see how Smart Pointers fit into this kind of problem), here it is:
std::unique_ptr<double[]> A = std::make_unique<double[]>(4);
std::unique_ptr<double*[]> a = std::make_unique<double*[](2);
for (size_t q = 0, k = 0; k < 2; k++){
a[k] = A.get() + q;
q += 2;
}
One of the primary uses of pointer-to-pointer in C is to return a pointer value:
error_t Allocate Object(Object ** ptr);
While the same will work in C++ it can be made somewhat more intuitive by making the function take a reference-to-pointer instead of pointer-to-pointer:
error_t AllocateObject(Object *& ref);
This way the calling code can simply pass the pointer variable (instead of needing to use & to take its address) and the function definition can simply assign to the parameter (rather than needing to dereference it with *).
The modern C++ equivalent of your example code would use smart pointers for ownership, and iterators to access array elements:
#include <array>
#include <memory>
int main()
{
// Define our types:
using A_array = std::array<double, 4>;
using A_iterator = A_array::iterator;
// Make smart pointers to manage ownership for us:
auto const A = std::make_unique<A_array>();
auto const a = std::make_unique<std::array<A_iterator, 2>>();
// Normally, we'd just put these in automatic storage, as
// they are small, and don't outlive the function scope:
// A_array A;
// std::array<A_iterator, 2> a;)
{
// Populate a with iterators to A's elements
auto target = A->begin();
for (auto& element: *a) {
element = target;
target += 2;
}
}
// No need for delete[] at end of function or at any other
// return statement.
}
I'm new to using C++ for complicated programming. I've been sifting through some leftover, uncommented, academic code handed down through my department, and I've stumbled across something I have no real idea how to google for. I don't understand the syntax in referencing an array of structs.
Here is a trimmed version of what I'm struggling with:
typedef struct
{
double x0,y0;
double r;
} circle;
double foo()
{
int N = 3;
double mtt;
circle circles[N];
for (int i = 0; i < N; i++)
{
mtt += mtt_call_func((circles+i), N);
}
return mtt;
}
What does (circles+i) mean in this case?
EDIT: the function should have (circles + i), not (circle + i).
circles+i is equivalent to &circles[i]. That's how pointer arithmetic works in C++.
Why is there a pointer? Well, when you give the name of an array, in a context other than &circles or sizeof circles, a temporary pointer is created that points to the first member of the array; that's what your code works with. Arrays are second-class citizens in C++; they don't behave like objects.
(I'm assuming your circle+i was a typo for circles+i as the others suggested)
circle+i means "take a pointer circle and move it i times by the size of the object pointed to by it". Pointer is involved because the name of the array is a pointer to it's first element.
Apart from this you should initialize an integer counter variable that is used in loop:
for (int i = 0; i < N; i++)
^^^^
{
mtt += mtt_call_func( ( circles + i), N);
^ // typo
}
In C, as in C++, it is legal to treat an array as a pointer. So circles+i adds i times the size of circle to the address of circles.
It might be clearer to write &circles[i]; in this form, it is more obvious that the expression produces a pointer to the ith struct in the array.
Each vector you declare in stack it's actually a pointer to the first index, 0, of the vector. Using i you move from index to index. As result, (circles+i) it's the equivalent of &circles[i].
& means the address of the variable. As in your function call, you send a pointer which stores an address of a variable, therefore & is required in front of circles[i] if you were to change to that, as you need the address of the i index of the vector circles to run your function.
For more about pointers, vectors and structures check this out: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
It should cover you through ground basics.
I'm looking at some source code and within the code it has some code I don't fully understand. Below is a basic pseudo example that mimics the part I'm having trouble understanding:
float *myArray;
object(){
myArray = new float[20];
}
~object(){
}
void reset(){
delete [] myArray;
}
void myMethod(float *array){
for (int i = 0; i < 20; i++){
array[i] = 0.5f;
}
}
Now in another method body there's:
void mySecondMethod(){
myMethod(myArray + 10);
}
It's the second method I don't get: What does it mean when you pass an array pointer and an int into a parameter that wants an array pointer? I'm just trying to bolster my knowledge, I've been trying to search about it but have found no information.
It simply means "the address of the 11th element in this array".
This is an example of pointer arithmetic, a core feature of C (and also of C++ although it's perhaps considered a bit "low-level" there).
The expression means "take the address of the first element of myArray, and add the size of 10 elements to that".
It works the same as myArray[10], since the indexing operator is really sugar for *(myArray + 10).
myArray[10] == *(myArray + 10)
&myArray[10] == myArray + 10
Can anyone hint on how to pass by reference an array of the kind
int array[2][3][4];
so that I may save his pointer in order to use and modify the array?
Like, if I were speaking about a single integer:
// Scope 1
int a = 3;
increment(&a);
// End Scope 1
// Scope 2
int *pa;
void increment(int *tpa) {
pa = tpa; *pa++;
}
// End Scope 2
Thanks a lot and best regards.
If you really want to pass the array by reference, you can do so:
void f(int (&a)[2][3][4]) { }
In C, which doesn't have references, you can pass the array by pointer (this works in C++ too, of course):
void f(int (*a)[2][3][4]) { }
C++:
void f(int (&array)[2][3][4])
{
}
C: There are no references in C
Note that no matter how you pass the array, via reference or not, the array is not going to be copied, so you'll get the original pointer. You can pass this array also like this:
void f(int array[][3][4])
{
}
Thanks to everyone who participated in this! sskuce provided a very good solution, taking advantage of a "container". I had thought about this but didn't really like the extra stuff.
I realized after a little jumbling that James McNellis had given the answer all along. So... here's the solution I prefer with no containers and no indexes arithmetic (mind the parenthesis):
void Scope1()
{
int array[2][3][4];
Scope2(&array);
}
int (*pArray)[2][3][4];
void Scope2(int (*tpArray)[2][3][4]))
{
pArray = tpArray;
(*pArray)[0][0][0] = 3;
}
Thanks again to everyone.
Edit: I'm keeping my original answer below, as I believe it's necessary for folks to understand how arrays are actually passed to functions and how they're layed out in memory, but on further reflection I think there is a simple and correct way to get what you want done.
Encapsulate the array within a struct, e.g.
typedef struct ArrayHolderStruct{
int array[2][3][4];
} ArrayHolder
//...
//scope 1
ArrayHolder thingy;
thingy.array[0] = something;
//other initialization.
F( &thingy );
//...
//scope 2
ArrayHolder *pa;
void F ( ArrayHolder *p ){
pa = p;
p->array[0][1][2] = 42;
}
//Call F first to set pa.
void G(){
pa->array[0][1][2] = 6 * 9; // if pa = &thingy, thingy will be modified.
}
The struct will allow you to maintain layout information about the encapsulated array, and you don't have to worry about nasty index arithmetic.
-----OLD ANSWER-----
Passing a reference to an array is not useful, unless you want to change the size or layout of the array (which you can't do with statically sized arrays anyway). You'll get a reference (or pointer) to the elements of the array even if you pass the array by "value". That is to say, if you declare your function:
void f ( int a[2][3][4] ){
a[0][1][2] = 42;
}
and call it like f( array ) when f exits, array[0][2][2] will have been set to 42, even though you didn't pass a "reference" to array into the function.
If you want to save a pointer to the array for later use in a library function, etc, you could do something like:
//scope 2
int * pa;
void f ( int a[2][3][4] ){
pa = &a[0][0][0];
}
It gets tricky at this point - you have to know how pa is layed (laid?) out in memory. I think C has standardized on 'row major order', so the array should be layed out in memory like:
a[0][0][0] a[0][0][1] a[0][0][2] a[0][0][3] a[0][1][0] ... a[0][2][3] a[1][0][0] a[1][0][1]... a[1][2][3]
So, to get at an element at index [n][j][k], you have to do something like:
pa[n * 12 + j * 4 + k] = something;
Basically, multiply each index by the number of elements that can be referenced by an index of that order, e.g. each k index points to exactly one element given a fixed j and n index, each j index can point to 4 elements given a fixed n index, and each n index can point to one of 12 (because 12 = 3 * 4) elements.
Like I said, it's tricky. See the wikipedia articles on Array Data Structures and Row-major order to get a better understanding of how these things are layed out.