www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static array of pointers to dynamic arrays of ints problem...

reply WhatMeForget <kheaser gmail.com> writes:
Surely a stupid mistake on my part, but why is the first array 
repeated?


import std.stdio;

void main()
{
     int[]*[2] a;  // a static arrray holding pointers to dynamic 
arrays

     static int unique = 0;

     foreach(i, elem; a)
     {
         int[] temp = new int[](5);
         foreach(ref element; temp)
         {
             element = unique;
             unique++;
         }
         writeln("temp = ", temp);
         a[i] = &temp;
     }

     foreach(i, elem; a)
     {
             writeln(a[i].length);
             writeln("[", i, "][]", *a[i]);
     }
}

temp = [0, 1, 2, 3, 4]
temp = [5, 6, 7, 8, 9]
5
[0][][5, 6, 7, 8, 9]
5
[1][][5, 6, 7, 8, 9]
Apr 21 2018
next sibling parent Neia Neutuladh <neia ikeran.org> writes:
On Sunday, 22 April 2018 at 06:00:15 UTC, WhatMeForget wrote:
     foreach(i, elem; a)
     {
         int[] temp = new int[](5);
 ......
         a[i] = &temp;
     }
You're taking the address of a local variable and persisting it beyond the variable's scope. This is not safe in general; compilers regularly reuse spaces on the stack. DMD specifically tends to do this reliably with foreach loop bodies. You see the same thing in C: #include <stdio.h> int main(int argc, char** argv) { int* p[2]; for (int i = 0; i < 2; i++) { int f = i; p[i] = &f; } printf("p[0] = %x, *p[0] = %d\n", p[0], *p[0]); printf("p[1] = %x, *p[1] = %d\n", p[1], *p[1]); return 0; } Which prints something like: p[0] = d9b69428, *p[0] = 1 p[1] = d9b69428, *p[1] = 1
Apr 21 2018
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/22/18 2:00 AM, WhatMeForget wrote:
 Surely a stupid mistake on my part, but why is the first array repeated?
In addition to what Neia said, you shouldn't use pointers to dynamic arrays. Such things are really hard to allocate on the heap, since new int[] just makes an array, not a pointer to an array. You're way more likely to accidentally store pointers to stack variables (as demonstrated). The only way 2 ways I know of to do it are to a) allocate a multi-dimensional array, and take it's pointer (e.g. (new int[][1]).ptr) or b) create a dummy struct with an array in it, and new that: Struct Dummy { int[] array; } auto p = new Dummy; auto ptr = &p.array; Just use int[][2] a, you will be better off. -Steve
Apr 23 2018