I am working on some legacy code. I have the following data types:
typedef struct {
char *name ;
ColumnType type ;
unsigned pos ; //column position in table
CellData **data ; //ptr to list of cells in column
}Column ;
struct _table {
char name[TABLE_NAME_LEN+1] ;
unsigned int num_rows ;
unsigned int num_cols ;
Column **cols ; //ptr to list of columns
};
struct _table m_
In the source code, there is the following statement:
m_table.cols = new Column*[m_table.num_cols];
I am familiar with new[], but I'm no sure what the multiplication operator is doing there - can any explain?
It's not multiplication. The symbol * has many, many completely different meanings in C++, all depending on context.
In your case, you're creating a dynamic array of Column*, i.e. of pointers to Column.
In other words, you're saying new T[N];, where T = Column*.
It's not a multiplication operator. It's instead allocating an array of Column* (pointer to Column type). The resulting array stores pointer values
m_table.cols = new Column*[m_table.num_cols];
m_table.cols[0] = Column(); // Error: Expected Column* got Column
m_table.cols[0] = new Column(); // Ok
In your case Column* is a type (for pointers to instances of Column class) and you create an array of them.
It's not a multiplication operator. It's allocating an array of pointer-to-Column, rather than an array of Column.
It's not a multiplication operator, it's a pointer specification i.e. "pointer to Column".
The * denotes a pointer. So you're creating an array of Column pointers.
Related
What is the use of a * after new int in this code? Why can't we write 2d array without * after new int?
int *p1=new int[3];
int *p2=new int[3];
int **pData= new int*[2];
The use of the * after new int is, as you said, for the 2d array.
Without the *, it is simply a 1d array.
There is a similar question which could be useful:
link
new int*[2] says to allocate storage for an array of 2 int*. There's nothing special here: int* is the name of the type being created. The code uses that array of int* to create a 2-dimensional array, but that's in the rest of the code; new int*[2] on its own is simply an array of pointers.
But, yes, you can create a 2-dimensional array directly, without that intervening layer of pointers:
int (*p)[3] = new int[2][3];
This defines p to be a pointer to an array of 3 int. And, because the new expression gives the dimension for that array, you've got a 2-dimensional array. It acts just the way you'd hope for:
p[1][2] = 7;
std::cout << p[1][2] << '\n';
* is a pointer, check this answer out for an explanation of using pointers in C++
Im struggling to understand something with this code:
int **p_p_tictactoe;
p_p_tictactoe = new int*[ 3 ];
for ( int i = 0; i < 3; i++ )
{
p_p_tictactoe[ i ] = new int[ 3 ];
}
on the line: p_p_tictactoe[i] = new int [3]; The square brackets dereference p_p_tictactoe once so that we are looking at the value at the address stored by p_p_ticatactoe which is another address as it is a pointer to a pointer. Then this address is assigned to a new int but shouldn't this be assigned to the value at the address rather than the address itself like this: *p_p_tictactoe[i] = new int[3]
p_p_tictactoe is an int **.
Therefore, p_p_tictactoe[i] must be an int *.
Therefore, *p_p_tictactoe[i] must be a single, lonely, int.
Assigning the result of new, which would be an int * here, to an int will not have any useful results.
Another helpful way of looking at this: *p_p_tictactoe[i] is equivalent to p_p_tictactoe[i][0]. That, obviously, is an int, a single cell, and stuffing a pointer into it, won't work.
No.
*p_p_tictactoe[i] (also spelt p_p_tictactoe[i][0]) will be one of the ints in the array that you're creating on that line.
As an aside, this is a very inefficient memory layout. Unless your array is likely to change dimensions, or is jagged, prefer a single block of ints with 2D indexing faked on top.
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 have this code - http://ideone.com/wslBnj
#include <stdio.h>
int main(void) {
int array[2][3] = {5,10,15,20,25,30};
int (*ptr)[2][3] = &array; // line 1
printf("%d\n",***ptr);
printf("%d\n",*(*ptr)[1]);// line 2
printf("%d\n",(*ptr)[1][2]);
return 0;
}
I don't understand the LHS(left hand side) syntax at 'line 1'. What does it mean (in words)?
I don't understand the priority given in 'line 2'. I mean, the output could be for (*(*ptr))[1] this grouping, but it was for this *((*ptr)[1]). Why is that?
Can someone explain both the doubts in detail? I couldn't understand the search terms to search for this question on internet. That's why I am asking it directly here.
I don't understand the LHS(left hand side) syntax at 'line 1'. What
does it mean (in words)?
In C, declarations follow use.. It means that (*ptr)[2][3] is of type int (well, technically, [2][3] would be out of bounds, but you get the point). Anyway, this implies that (*ptr) is a multi-dimensional array of ints - namely, a 2x3 array of ints. Therefore, ptr is a pointer to an array[2][3] of ints.
I don't understand the priority given in 'line 2'. I mean, the output
could be for (*(*ptr))[1] this grouping, but it was for this
*((*ptr)[1]). Why is that?
Indexing has higher priority than dereferencing. Thus, *(*ptr)[1] is equivalent to *((*ptr)[1]), and in this case it is equivalent to (*ptr)[1][0], since (*ptr)[1] is an array of 3 ints.
This line
int (*ptr)[2][3] = &array; // line 1
declares a pointer ( *ptr ) to an object of type int[2][3] That is it is a pointer to two dimensional array of type int[2][3]
If you would not use parentheses
int * ptr[2][3];
then the declaration would mean a two dimensional array of pointers of type int *
In line #2 expression
*(*ptr)[1]
is evaluated in the following order.
1. ( *ptr )
As ptr is declared as an pointer to a two dimemsional array then dereferencing the pointer will give the object pointed to by the pointer. So ( *ptr ) means array
int array[2][3]
2. ( *ptr )[1]
is the reference to the second row of the array
and at last in this expression
3. *( *ptr )[1]
the array ( *ptr )[1] that is the second row of the array "array" is converted to pointer to its first element and this pointer is dereferenced. So as result *( *ptr )[1]the first element of the second row of array "array" that is you will get 20.
Operator * that is an unary operator has lower priority than operator [] and is evaluated right to left.
From the C++ Standard
5.3 Unary expressions
1 Expressions with unary operators group right-to-left.
Thus if you will write for your array "array" expression
**array
then at first there is evaluated subexpression *array that will yield the reference to the first row of the array and then *( *array ) will yield the first element of the first row.
int (*ptr)[2][3] could also mean a pointer to the first [2][3] matrix in a 3d array, for example:
int array[2][2][3] = {{{4,8,12},{8,16,24}},{{5,10,15},{20,25,30}}};
int (*ptr)[2][3] = array; // note &array is not used here
Newbie question here...why does the following code only work with a 1D array but not a 2D array? Shouldn't it not make a difference whether b is pointing to the start of a 1D array or a 2D array, as long as it's a char* pointer (as it is)? I thought that the general notation [bound1][bound2] was an equivalent of [bound1*bound2], even over the assignment operation. Help?
main() //this works fine
{
char *b;
b = new char[50];
return 0;
}
.
main() //but this raises the error "Cannot convert char(*)[50] to char* in assignment"
{
char *b;
b = new char[50][50];
return 0;
}
char[50]; is array of 50 elements of type char. Each element has type char. So new char[50]; returns a pointer to first element: char * - pointer to char.
char[50][50] is NOT array of char. It is array of arrays. Each element has type char[50]. So new char[50][50]; returns a pointer to first element: char (*)[50] - pointer to char[50].
Declare b this way:
char (*b)[50];
Test: http://ideone.com/1zJs1O
If your were right with that [bound1][bound2] and [bound1*bound2] were equivalent you wouldn't have created a 2D array. The size of allocated memory, that's what your multiplication implies, is not the problem here, it's about different data types: A 1D array is simply not a 2D array and that's what the compiler is telling you. You should read about C++ type system and type safety.
What is type safety and what are the "type safe" alternatives?