Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Role of Parantheses in array of pointers in C++

Tags:

c++

Trying to implement Graphs using this link, I came across a serious syntax doubt.

/ A structure to represent an adjacency list node
struct AdjListNode
{
    int dest;
    struct AdjListNode* next;
};

// A structure to represent an adjacency liat
struct AdjList
{
    struct AdjListNode *head;  // pointer to head node of list
};

// A structure to represent a graph. A graph is an array of adjacency lists.
// Size of array will be V (number of vertices in graph)
struct Graph
{
    int V;
    struct AdjList* array;
};

In the I mentioned above, it is implemented in C, whereas I have implemented it in C++. And now a function to create the Data Structure of the Graph:

struct Graph* createGraph(int V) {
  struct Graph *graph;
  graph = new (struct Graph);
  graph->V = V;

  //the problem line below   
  graph->array = new (struct AdjList)[V];
  //initialize all the elements in the array as NULL
  for(int i = 0; i < V ; i++) {
    graph->array[i].head = NULL;
  }
  return graph;
}

This code gives the error :array bound forbidden after parenthesized type-id Whereas if I just remove the paranthese from the problem line, everything works fine. Why is this happening?

EDIT:

I know how to fix the problem. Just need to do this.

graph->array = new struct AdjList[V];

The question is WHY is it incorrect?

like image 820
SLearner Avatar asked Nov 20 '25 04:11

SLearner


2 Answers

"The question is WHY is it incorrect?"

The chapter 5.3.4 of the c++ language specification, pretty clearly shows that the parenthesis immeadeatly following the new keyword are preseved for placement new expressions:

enter image description here

like image 167
πάντα ῥεῖ Avatar answered Nov 21 '25 18:11

πάντα ῥεῖ


There are two common new expression variants that allows parenthesis between the keyword and the type. The entities enclosed within go in as arguments to the operator new function. They're useful

  1. To specify the memory manually instead of using the default operator new function.
  2. To specify a no-throw behaviour. This is handy when you don't want the new expression to throw a std::bad_alloc when freestore allocation fails.

1. placement new

char* ptr = new char[sizeof(T)];   // allocate memory
T* tptr = new(ptr) T;              // construct in allocated storage ("place")
tptr->~T();                        // destruct

2. nothrow

auto p* = new (std::nothrow) char;

This will not throw but would set p to nullptr if the allocation fails.

The question is WHY is it incorrect?

Because it isn't part of the allowed grammar where the parenthesis can occur; the error array bound forbidden after parenthesized type-id means the compiler thinks you did this

T *arr = new (T) [count];

which is invalid since for an array, you do

T *arr = new T[count];

i.e. the type without parenthesis. Here, as mentioned in comments by juanchopanza, the type is T[], so you could do T *arr = new (T[count]);.

like image 43
legends2k Avatar answered Nov 21 '25 19:11

legends2k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!