446,234 Members | 2,075 Online
Need help? Post your question and get tips & solutions from a community of 446,234 IT Pros & Developers. It's quick & easy.

# C++ Puzzle

 P: 34 Hello all, I got one question from my colleagues to answer. The question is: " How can I declare an array with only one element and still access elements beyond the first element (in a valid fashion)? " But, I could not answer, Can anyone please help me to solve this problem? Thanx in advance Suyash Jun 7 '07 #1
6 Replies

 Expert 100+ P: 181 Hello all, I got one question from my colleagues to answer. The question is: " How can I declare an array with only one element and still access elements beyond the first element (in a valid fashion)? " But, I could not answer, Can anyone please help me to solve this problem? Thanx in advance Suyash You can do something like this Expand|Select|Wrap|Line Numbers struct dynamic { int a[1] };   struct dynamic * ptr = (struct dynamic *) malloc(size of struct dynamic + 100 * sizeof(int)); now u can use ptr->a[1], ..... 100 Many say this code is not portable. But i really dont know y they say so. :( Jun 7 '07 #2

 P: 33 Hello all, " How can I declare an array with only one element and still access elements beyond the first element (in a valid fashion)? " If you declare an array of one or several elements using [] or pointers (*), it seems to me there is no way to access elements beyond the range you specify in your declaration and safely ensure the integrity of the data at this position. I mean if you do: Expand|Select|Wrap|Line Numbers char array1[]="a" //fixed size array of 1 element char *array2="a" //variable size array, currently dimensioned for 1 element   You would be able to retrieve the character 'a' by doing: Expand|Select|Wrap|Line Numbers std::cout << array1[0] // Outputs 'a' std::cout << array2[0] << *array2(0) // Outputs "aa"   Anything you try to retrieve beyond the range of your array is undefined. It's because this space of memory is not reserved for your array, so any other process might me using it, or not, so you can't predict what is its content. Furthermore, you should not write in a memory address not allocated specifically for your process, as you might alter data used by another program. Actually, the array definition written above could also be done the following way and it would be exactly the same: Expand|Select|Wrap|Line Numbers char array1[]={'a','/0'} char *array2={'a','/0'}   So it's really in trying to retrieve array1[2] and array2[2] that you will not know what you'll get. Finally, there is no way to access valid data outside the range you specify. However, while when you declare a fixed size array you're stuck with it in your entire program, if you declare a variable size array, then you could redefine it several times. Ras. Jun 7 '07 #3

 P: 34 Thanx for your reply, But why it is necessary to use pointers:- Following code produces same result upto some extent( till 4th-5th elements):- Expand|Select|Wrap|Line Numbers #include using namespace std;   struct exp {     int a[1]; };     int main() {     struct exp s;     for(int i=0;i<4;i++)         s.a[i]=i;     cout<

 Expert 100+ P: 1,251 Thanx for your reply, But why it is necessary to use pointers:- Following code produces same result upto some extent( till 4th-5th elements):- Expand|Select|Wrap|Line Numbers #include using namespace std;   struct exp {     int a[1]; };     int main() {     struct exp s;     for(int i=0;i<4;i++)         s.a[i]=i;     cout< using namespace std;   struct exp {   int a[1];     static size_t sizeOfExp(size_t numElements)   {     return sizeof(exp) + sizeof(int) * (numElements-1);   }     static exp* allocate(size_t numElements)   {     // inplace constructor     return new(::operator new(sizeOfExp(numElements))) exp();   } };     int main() {     exp * s = exp::allocate(20);     for(int i=0;i<4;i++)         s->a[i]=i;     cout<a[i]<<" ";     delete s;     return 0; } However, if your array is not a base type, you should also override the delete operator and keep track of the number of elements with a variable. You can remove this problem using a template, but that brings other issues. Expand|Select|Wrap|Line Numbers template struct exp {   int a[size]; };   C/C++ does not do bounds checking on raw arrays. Some containers may, but I'm not sure if the STL ones do. Adrian Jun 7 '07 #5

 P: 33 But why it is necessary to use pointers:- It's got nothing to do with using pointers or not, or using structs or not. Chek my previous answer, it also tells why you can't do: Expand|Select|Wrap|Line Numbers struct exp {     int a[1]; };   int main() {         ...     for(int i=0;i<4;i++)         cout<

 Expert 100+ P: 1,251 Or a seg fault/page fault. Sometimes there is no physical memory allocated after an allocated section. On OSs that support memory mapping this can be done to catch boundry overrun errors. Adrian Jun 9 '07 #7