I'm working in Vs2010 c++ with 2D arrays.
I started off with a 1D pointer and used the operation [] as the following:
class CMatrix
{
void clear();
public:
int nRows;
int nCols;
short * MyMat;
CMatrix();
CMatrix(int r,int c);
~CMatrix(void);
void SetMatrix(int r,int c);
short * operator[] (const int row)
{
return MyMat + (row*nCols);
}
};
I don't mind to change to 2D pointer.
However my problem is with debug. Because I'm using pointers I can't see the arrays content.
Are there any another options ?
I prefer not to use vector.
One way is to use use the Memory viewer.
While debugging ( when stoped at a Breakpoint ), goto the menu Debug > Windows > Memory > Memory 1 to get the memory viewer. Then type-in the memory address ( copy paste the value from your pointer ) so that you can view the memory around that area of your program memory.
When you right click on memory viewer you can choose how you want to view the data ( as ANSI , as 4 integers, as 2 byte integers , as floats , bla bla... )
Also you can use the Watch window at the debug time. just use your pointer as an array ( e.g. if your pointer is char * t, the syntax t[0] will give your data pointed by the pointer t
In the QuickWatch window, you can type the name of the pointer variable followed by a comma and the number of array indices you want to view, e.g. MyMat, 10.
Related
I am trying to make a void function where it changes the pointer that I pass. The code is throwing an exception on one of the lines and i'm not sure why. Could it be I cannot pass the arrays as pointers then implement math on it? I thought I deallocated the pointers to fix it but this seemed to not work.
Void function:
#include <iostream>
using namespace std;
void* func2(int one, double *value1[], int two, double *value2[], double *final1) {
double testval;
double finalval = 0;
//double *final1;
double final = 0;
for (int i = 1; i < one; i++) {
for (int j = 1; j < two; j++) {
testval = *value1[i] * *value2[j]; //exception thrown (works up to this point)
finalval = testval + finalval;
}
final = finalval + final;
}
*final1 = final;
return 0;
}
Main Function:
int main(){
double *array1 = new double[input1];
double *array2 = new double[input2];
//for loop that takes user input and fills in array1 and array2 with size and a list of values
...
double testval2;
func2(input1, &array1, input2, &array2, &testval2);
cout << testval2 << endl;
delete[] array1;
delete[] array2;
return 0;
I am relatively new to pointers, so my apologies if the code is a little illiterate.
It looks like you want to pass two 1D arrays to func2().
One way to do that is remove the [] from the function signature as
(int one, double *value1, int two, double *value2, double *final1)
Within the function, change *value1[i] to value1[i], and similarly for value2. And remove the & when calling the function from the main().
A couple other thoughts:
I'm not sure how an exception could throw from your code. But *value1[i] is definitely an invalid memory access, so what you may have seen is a segmentation fault message. A helpful tool to troubleshoot these kinds of errors is AddressSanitizer, enabled in clang or gcc by compiling with -fsanitize=address, or if you are using Xcode, there is an option for it. Another great tool is valgrind.
Manually allocating dynamic arrays is a pretty C-like way of using C++. In C++, it is idiomatic to create the arrays as std::vector objects, which under the hood works the same way (it also allocates a dynamic array) but has a more convenient interface. Particularly the vector cleans itself up automatically, so no need to call delete[], and the vector knows its own size, so no need to pass the size around as a separate parameter as with dynamic arrays.
Edit: Here is a note to clarify why the original code manages to compile but fails at runtime.
In the function signature, the combo of both * and [] on double *value1[] makes value1 a pointer to a pointer to double, equivalent to double **value1. In main(), array1 is a double*. When calling the function, &array1 takes the address of that double*, obtaining a double**. So the type matches and the code compiles.
The code fails at runtime on *value1[i]. value1 is a pointer to pointer to doubles, where the inner pointer points to the dynamic array. So what was intended is (*value1)[i] to first dereference the outer pointer, then subscript into the dynamic array. However, in C++, subscripting (a[]) has operator precedence over dereferencing (*a), so it is read in backward order as *(value1[i]). Subscripting the outer pointer value1[i] is invalid for nonzero i, reading memory from somewhere in the stack and arbitrarily interpreting it as a double*. Then the surrounding *( ) attempts to dereference this busted pointer. The machine's memory protection catches this, and the OS sends a "SIGSEGV" signal or similar to the program to kill it.
I'm searching for an example or explanation why someone should (or should not) use triple-pointers in C/C++.
Are there any examples where triple-pointer arise?
I am especially looking for source-code which uses triple-pointers.
The best example that comes to mind is a sparse multi-level table. For instance one way to implement properties for Unicode characters might be:
prop_type ***proptable;
...
prop_type prop = proptable[c>>14][c>>7&0x7f][c&0x7f];
In this case proptable would need to have a triple-pointer type (and possibly quadruple pointer if the final resulting type is a pointer type). The reason for doing this as multiple levels rather than one flat table is that, at the first and second levels, multiple entries can point to the same subtable when the contents are all the same (e.g. huge CJK ranges).
Here's another example of a multi-level table that I implemented; I can't say I'm terribly proud of the design but given the constraints the code has to satisfy, it's one of the least-bad implementation choices:
http://git.musl-libc.org/cgit/musl/tree/src/aio/aio.c?id=56fbaa3bbe73f12af2bfbbcf2adb196e6f9fe264
If you need to return an array of pointers to variable length strings via a function parameter:
int array_of_strings(int *num_strings, char ***string_data)
{
int n = 32;
char **pointers = malloc(n * sizeof(*pointers));
if (pointers == 0)
return -1; // Failure
char line[256];
int i;
for (i = 0; i < n && fgets(line, sizeof(line), stdin) != 0; i++)
{
size_t len = strlen(line);
if (line[len-1] == '\n')
line[len-1] = '\0';
pointers[i] = strdup(line);
if (pointers[i] == 0)
{
// Release already allocated resources
for (int j = 0; j < i; j++)
free(pointers[j]);
free(pointers);
return -1; // Failure
}
}
*num_strings = i;
*string_data = pointers;
return 0; // Success
}
Compiled code.
If you use a linked list you have to store the address of the first element of the list ( first pointer ) .
If you need to change in that list you need another pointer ( two pointer)
If you need to pass your list that you are changing in two pointers and change it in another function you need another pointer ( three pointer )...
They are a lots of examples
I've used triple pointers in C++:
There is an interface written for a Java program:
https://github.com/BenLand100/SMART/blob/master/src/SMARTPlugin.h
and it takes an array of strings.
typedef void (*_SMARTPluginInit)(SMARTInfo *ptr, bool *replace, int *buttonc, char ***buttonv, int **buttonid, _SMARTButtonPressed *buttonproc);
Then in my program I do:
char* btnTexts[2] = {"Disable OpenGL_Enable OpenGL", "Enable Debug_Disable glDebug"}; //array of C-style strings.
void SMARTPluginInit(SMARTInfo* ptr, bool* ReplaceButtons, int* ButtonCount, char*** ButtonTexts, int** ButtonIDs, _SMARTButtonPressed* ButtonCallback)
{
*ButtonText = btnTexts; //return an array of strings.
}
but in C++, you can use a reference instead of pointer and it'd become:
void SMARTPluginInit(SMARTInfo* ptr, bool* ReplaceButtons, int* ButtonCount, char** &ButtonTexts, int** ButtonIDs, _SMARTButtonPressed* ButtonCallback)
{
ButtonText = btnTexts; //return an array of strings.
}
Notice now that "ButtonTexts" is a reference to an array of C-style strings now.
A char*** can be a pointer to an array of C-style strings and that's one time that you'd use it.
A very simple example is a pointer to an array of arrays of arrays.
Triple pointer is a pointer variable that points to a pointer which in turn points to another pointer. The use of this complex programming technique is that usually in which companies process tons and tons of data at one time .A single pointer would point to a single block of data (suppose in a large file) using the triple pointer would result in 3 times faster processing as different blocks of data(in the same file) can be pointed by different pointer and thus data could be accessed/processed faster (unlike 1 pointer going through the whole file).
I'm attempting to make a maze-solving program, and while the algorithm is sound (at least in my head), I've been running into a roadblock with 2D arrays. I'm coming from C# and Java, so the syntax is giving me grief.
Here's an SSCCE:
//Main.cpp
#include "MazeSolver.h"
int main()
{
MazeSolver mazeSolver;
char maze[51][51] = { }; // Not bothering to show code for populating the array
mazeSolver.setMaze(maze);
}
//MazeSolver.cpp
#include "MazeSolver.h"
MazeSolver::MazeSolver() { }
void MazeSolver::setMaze(char maze[51][51])
{
this->maze = maze;
}
//MazeSolver.h
#ifndef _MAZESOLVER_H
#define _MAZESOLVER_H
class MazeSolver
{
private:
char **maze; // This is likely the problem, I'm at wits end in regards to
// what notation is needed here. I do not want to hard-copy
// the entire array, I just need to access it (via pointer)
// I've also tried just using char maze[51][51] here, char *maze, etc...
public:
MazeSolver();
void setMaze(char maze[51][51]);
}
You cant assign (Or convert) 2d arrays (array[ROWS][COLUMNS]) to pointers to pointers (aka **) because the memory layout of a 2d array is (could be) very different to the memory layout the pointer of pointers could point to.
Check this thread for more info about this topic.
If suggest you to use the de facto C++ standard container, std::vector, instead of a plain array:
class MazeSolver
{
std::vector<std::vector<char>> maze;
void setMaze( const std::vector<std::vector<char>>& new_maze )
{
maze = new_maze;
}
};
Note that a vector has size 0 by default (At the point of its initialization), so you should fill it with elements:
for( std::size_t i = 0 i < ROWS ; ++i )
{
maze.push_back( std::vector<char>() );
for( std::size_t j = 0 ; j < COLUMNS ; ++j )
maze[i].push_back( ' ' );
}
However, C++11 (The current iteration of the language) has a std::array container which is like a C array but with the interface of other Standard Library Containers:
std::array<char,ROWS*COLUMNS> maze;
<rant>
This is one of the weird quirks of C++.
C++ 2D arrays are NOT jagged arrays. When you declare char maze[51][51], it actually allocates 1 contiguous array 51*51 members long. sizeof(maze) == 51*51. When you dereference a value, maze[a][b], what it actually does is *(maze+51*a+b). All this is under the hood.
A Jagged Array is an array of arrays, a char**. In this case, you have an array of 51 pointers size == (51*sizeof(void*)). In each position, the pointer points to a completely different memory location, allocated to 51 members long.
This is ANNOYING because you can't just convert the two, even by casting. You have to deal with weird syntax, such as char (*maze)[51] to get a pointer to the 2D array.
Whats even more annoying is the following happens:
int foo(int maze[51][51])
{
return sizeof(maze);
}
int maze[51][51];
int main(int argc, char** argv)
{
std::cout << sizeof(maze) << std::endl;//return 51*51*sizeof(int);
std::cout << foo(maze) << std::endl;//return 8, sizeof(void*);
}
So it implicitly passes by reference, not by value, which is opposite all the rest of C++.
</rant>
tl;dr;
The correct syntax for a pointer to a 2D array is char (*maze)[51];. Your syntax is for a jagged array (arrays of arrays) which is NOT the same thing in C++.
I am pretty weak in understanding and working with pointers. So, Please help me here.
My objective is to pass an array pointer's address to a function ,(i.e.) the address the pointer is pointing to, and update the values directly in the address using the '*' operator, in the function, to avoid any return values. Moreover, the length of this array has to be changed dynamically in the function to which it is passed. This is my attempt. If there's a better method to update the value of an variable, without having it returned from a function, please do mention that to help me.
But am getting errors, as I know I am doing it wrong, but still wanted to try with what I know, since I thought the best way to learn is to do and make as many mistakes as possible. Please help me here
This is the main function
int main()
{
double *trans;
int *rots;
readctrls(rots,trans);
for(int i=0;i<trans.size();i++)
{
cout<<trans[i]<<endl<<rots[i];
}
}
Here, am trying to pass the address of the pointer arrays to the function readctrls. then later, print its values. I haven't mentioned a size, cuz it will be determined later in the function.
The function is just to read numbers from a text file, line by line and store these numbers in these 2 arrays. The readctrls function is as follows.
void readctrls(int*& rots,double*& trans)
{
fstream inputs;
inputs.open("input_coods.txt");
int nol = 0,i = 0;
string line,temp,subtemptrans,subtemprots;
while(getline(inputs,line))
{
++nol;
}
cout<<nol<<endl;
inputs.close();
inputs.open("input_coods.txt");
string *lines = new (nothrow) string[nol];
trans = new double[nol];
rots = new int[nol];
for(int i = 0; i<nol ; i++)
{
getline(inputs,lines[i]);
temp = lines[i];
for(int j = 0; j<temp.length() ; j++)
{
if(temp.at(j) == ' ')
{
subtemptrans = temp.substr(0,j);
subtemprots = temp.substr(j+1,temp.length()-j);
trans[j] = ::atof(subtemptrans.c_str());
rots[j] = atoi(subtemprots.c_str());
}
}
}
inputs.close();
}
Thanks a lot for your help guys. I was able to understand a bit and changed the code and was able to compile now without errors. however, the value I read from file and load into the array, doesn't seem to get reflected back in the main. Am getting the correct values from the file when I print the array in the function, but am getting zeros, when I print in the main(). Please help me here.
These are the contents of the file
0.2 0
0.2 0
0.2 0
0.2 0
0.2 0
while print 'trans', which takes the first number every line, in the function, am getting the correct values. But while printing in the main function
0
0
0
0.2.
I changed the pointer to pointer reference while passing to function. Please check edit in the function code. Thanks in advance.
The declaration
void readctrls(int &rots,double &trans)
tells the compiler that rots and trans are references to a single value each. They are not pointers.
To make matters worse, you are actually trying to pass a pointer-to-pointer as arguments when calling this function.
You should change the declaration to actually take pointers:
void readctrls(int* rots, double* trans)
then change your call to not use the address-of operator (as those are already pointers):
readctrls(rots, trans);
Your code has several errors. Here are some of them:
double *trans = new double[];
int *rots = new int[]; //^^You need to give the size
for(int i=0;i<trans.size();i++)
{
cout<<*trans[i]<<endl<<*rots[i];
}
trans and rots are simply array of double and integers, you simply use trans[i] to print the i-th element. Dynamic arrays should be used similarly to static arrays. Take a look at this pointer and arrays for some basic understanding. Meanwhile, look at dynamic memory in C++ for some understanding on this point.
void readctrls(int &rots,double &trans);
//^^expects reference to int and double while you are not passing int and double from main
An array and a pointer can be thought about similarly as a way of referring to a range in memory. If you want to refer to a range of memory via pointers, then just pass the pointer to the function, ie
double pd* = new double[10];
fun(pd);
...
void fun(double* pd, int numDoubles)
{
do {
double d = magicDoubleGenerator();
*pd = d; // read as "the value that pd points to" or "contents of pd"
} while (++pd < pd + numDoubles);
}
Pointers are hard until one day you realize "Ahh! they just point at things!"
There are many errors ...
inputs.open("input_coods.txt"); // second argument is missing
check this fstream open
void readctrls(int &rots,double &trans)
change to
void readctrls(int* rots, double* trans) // this creates pointer rots trans
*trans = new double[nol]; // remove *
*rots = new int[nol]; // remove *
double *trans = new double[]; // not specified the size
int *rots = new int[]; // not specified the size
readctrls(&rots,&trans); // this means you passing address of pointer
trans.size() ; // this is c++ double is not a class
I am recommending you to study c++ from this site C++ Tutorial
Why in C/C++ it is needed for a func param that receives a MD arr to has the sizes of all sub arrays/dimensions?
here(PDF): It says the only difference of MD arrs is that
"the compiler remembers each imaginary dimension" but when I violate these dimensions compiler does nothing, e.g.:
char arr[3][5];
arr[0][5] = 10;
So, what's the point of remembering those sizes?
Indexed access into an array must compute memory offset calculations in row-major order based on the index value and declared inferior dimensions. More on that in a bit.
But first, your question is tightly related to this simple observation:
void foo( char a[] )
{
a[5] = 'a';
}
// caller of foo() from somewhere
char arr[5];
foo(arr);
Why does the compiler let you do that ?? Because this is C, and you're perfectly within your rights to shoot your own foot off with undefined behavior. Keeping this in mind:
void foo( char a[][5] )
{
a[0][5] = 'a';
}
// caller of foo() from somewhere
char arr[4][5];
foo(arr);
It is just as "valid" as the prior code (i.e. you're well within your right to enter into UB at your own risk and peril). In this case it will "work", but only because the linear backdrop of the underlying array is twenty elements wide, and we're only accessing the sixth element, which is technically arr[1][0].
The purpose of those inferior dimensions is to properly calculate access like this:
void foo( char a[][5] )
{
a[2][1] = 'b';
}
The 2 superior index must use the declared inferior dimension (in this case 5) to effectively calculate the the linear offset of the proper element. Laying out the 2D array in a 1D linear block, it is used to do this:
char arr[20]; // 4*5
arr[2*5+1] = 'b';
Note the 5. It, the declared inferior dimension, must be known to properly calculate the row-leap (figure of speech).
I hope that makes it at least a little clearer.
I should note that this compounds. I.e., the following:
char arr[3][4][5];
arr[1][2][3] = 'c';
effectively computes the correct location against the linear backdrop of the underlying array:
char arr[60]; // 3*4*5
arr[ 1*(4*5) + 2*(5) + 3 ] = 'c';
And so on. Take that out to as many dimensions as you desire. All the inferior dimensions must be known to do this properly.
An array is not a special kind of object, it's just a long list of items. Your arr[3][5] is in fact just an arr[15] and the arr[0][5] is then redirected to arr[5] by the compiler.
Because C/C++ don't store the sizes, you need to hardcode them to make the [0][5] map to [5] correctly.
Some compilers might enforce the [0][5] to be wrong (or warn about it), but since it maps to [5], it'll do at least something.