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
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.
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.
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.
here is my code and im not allowed to use a loop in the subarray function im pretty confused maybe someone can point me in the right direction i feel like im almost there..
int *duplicateArray(int *arr, int size)
{
int *newArray;
if (size<=0)
return NULL;
newArray = new int[size];
for (int index=0;index<size;index++)
newArray[index]=arr[index];
return newArray;
}
int* subArray(int *sub, int start, int length)
{
int aa[10]={1,2,3,4,5,6,7,8,9,10};
int *dup;
dup = aa;
duplicateArray(dup,10);
return dup;
}
int main()
{ cout << "Testing subArray: " << endl
<< "Expected result: 5, 6, 7, 8 " << endl;
int *subArr;
int start = 5;
subArr = subArray(subArr, 5,4);
for (int index = start; index<10; index++)
cout << subArr[index];
delete [] subArr;
subArr = 0;
So, since this is homework, I'm going to avoid posting a solution directly. You say that;
im not allowed to use a loop in the subarray function
Yet, currently, subArray calls duplicateArray, which uses a loop. This seems to be in conflict with the spirit of the requirement.
Since you haven't said otherwise, I'm assuming that subArray should duplicate the contents of its argument between start and the end. So, what do we know?
We know that the size of the returned array should be length - start elements. We also know (well, perhaps) that a function named memcpy exists which allows you to copy a block of bytes from one place to another (assuming they do not overlap).
(note that I am suggesting memcpy here because we are dealing with POD types (Plain Old Data) and because I doubt your class has delved into the STL. In the future you will be better served by something like std::copy(), but for now this is ok)
So, in order, we need to:
Declare a new array to return with length - start elements. You must dynamically allocate this array! Currently you are returning a pointer to a locally declared array. That pointer becomes invalid as soon as the function returns.
Copy length - start elements (elements, not bytes! Make sure to take into account the number of elements as well as the size of an individual element) from sub + start into this new array.
Return the new array (pointer really).
If I have somehow violated the requirements or intent of your assignment then you need to elaborate on your problem for me. Currently there is not much to go on.
Here we are once again good people of the internet.
This is the code I'm using:
//This is what is in the header file
int *myArr[]; // A two-dimensional array representing holding the matrix data
//This is what is in the definition file
Matrix::Matrix(int n, int m)
{
myRows = n;
myColumns = m;
initialize();
}
void Matrix::initialize()
{
*myArr = new int[myRows];
for (int i=0; i < 3; i++)//Only set to 3 since myRows is acting crazy
{
myArr[i] = new int[myColumns];
}
}
For some reason when I use myRows variable to create the myArr array it just seems to stop referencing the value it was pointing towards before.
For instance I give it the value 3 and after the *myArr = new int[myRows] has been executed it changes the value of myRows to 9834496, which I don't understand.
Does the "new" de-reference the variable or something?
Or am I doing something wrong?
Oh and since this is a school practice project (so I won't blame you if you don't answer) I would prefer an answer over working code, so that I could know what I did wrong for future projects.
int *myArr[];
This is wrong! You've to tell the compiler the size also, of your array of pointer. How about if you declare int a[]. You're telling the compiler to create an array of int, of unknown size, which is not allowed in C++. That is why you cannot do that.
I would suggest you to do this:
int **myArr;
void Matrix::initialize()
{
myArr = new int*[myRows]; //note int* here!
for (int i=0; i < myRows; i++)
{
myArr[i] = new int[myColumns];
}
}
This should work now.
Try replacing:
*myArr = new int[myRows];
by
myArr = new int*[myRows];
You should use std::vector<>. It deals with all the problems of memory allocation and deallocation.
And it does so without any bugs.
And then you focus yourself on the real goals of your algorithm. Not on memory management :-)
typedef std::vector<int> Ints;
typedef std::vector<Ints> Matrix;
Matrix myArray;
I'm not sure if you're project requires you to use multi-level pointers, if it doesn't another way you can approach this problem is to just treat the multi-dimensional array as one big flat array.
That means when you reach the end of a row, the index after that would be the first element of the next row. Here's how the code might look:
// In this approach the double pointer int**
// is replaced with just a simple int*
int *myArr;
// Here's your Matrix ctor. Note the use of the initializer list
Matrix::Matrix(int n, int m) : myRows(n), myColumns(m)
{
initialize();
}
void Matrix::initialize()
{
myArr = new int[myRows * myColumns];
/* This loop is no longer needed since we're allocating
one big chunk at once.
for (int i=0; i < 3; i++)//Only set to 3 since myRows is acting crazy
{
myArr[i] = new int[myColumns];
}
*/
}
// To retrieve stuff from your array
// you would do something like this:
int Matrix::operator() (const int x, const int y)
{
return myArr[x * myRows + y];
}