www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Dynamic memory

reply "Binarydepth" <binarydepth gmail.com> writes:
How do we get dynamic memory in D ?

I want to use memory based on user input. In this case declare a 
bi-dimensional array (int[2][var]), var being the user input.
Jul 24 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 24 July 2015 at 15:22:15 UTC, Binarydepth wrote:
 I want to use memory based on user input. In this case declare 
 a bi-dimensional array (int[2][var]), var being the user input.
Declare: int[2][] your_array; your_array.length = var; The runtime will handle the dynamic memory allocation for you when you set the length on a slice.
Jul 24 2015
next sibling parent reply "Binarydepth" <binarydepth gmail.com> writes:
On Friday, 24 July 2015 at 15:26:27 UTC, Adam D. Ruppe wrote:
 On Friday, 24 July 2015 at 15:22:15 UTC, Binarydepth wrote:
 I want to use memory based on user input. In this case declare 
 a bi-dimensional array (int[2][var]), var being the user input.
Declare: int[2][] your_array; your_array.length = var; The runtime will handle the dynamic memory allocation for you when you set the length on a slice.
this is what I did : int liCases [2][]; readf(" %d\n", &num);//Number of cases input liCases.length = num; And I get this error : prime1.d:26: error: constant liCases.length is not an lvalue
Jul 24 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 24 July 2015 at 15:33:45 UTC, Binarydepth wrote:
 int liCases [2][];
Those brackets are in the wrong place, you should write that as int[2][] liCases; The syntax you used there is a deprecated C compatibility feature. in C, arrays are defined differently and the dimensions go in the opposite direction than in D. (So int a[2][] in C means int[][2] in D - that's why the length doesn't change in that format.) But write it the D style for most consistency and it will work out. Just be aware that what I wrote is a dynamic array of two elements, not a two element group of dynamic arrays. So indexing is liCases[i][0] and liCases[i][1] rather than swapping those.
Jul 24 2015
parent reply "Binarydepth" <binarydepth gmail.com> writes:
Here is what I'm trying to do :

import std.stdio : readf, writef;
void main()	{
	int[2][] nam;
	int num;
	readf(" %d", &num);
	nam.length = num;
	foreach(nim; 0..num)	{
		readf(" %d %d", &nam[0][num], &nam[1][num]);
	}
	foreach(nim; 0..num)	{
		writef(" %d %d\n", &nam[0][num], &nam[1][num]);
	}
}

And here is the output I get when running the program :

core.exception.RangeError code.d(8): Range violation
----------------
0x406cfb _Dmain
	???:0
0x415fde void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll().void __lambda1()
	../../../../src/libphobos/libdruntime/rt/dmain2.d:408
0x41624e void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate())
	../../../../src/libphobos/libdruntime/rt/dmain2.d:383
0x4164a8 void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll()
	../../../../src/libphobos/libdruntime/rt/dmain2.d:408
0x41624e void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate())
	../../../../src/libphobos/libdruntime/rt/dmain2.d:383
0x4163d5 _d_run_main
	../../../../src/libphobos/libdruntime/rt/dmain2.d:416
0x7f51eb84ea3f __libc_start_main
	???:0
0x406088 _start
	???:0
0xffffffffffffffff ???
	???:0
----------------------------------------------------------------------------------

I just want to read and print data depending on user input.
Jul 28 2015
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 28 July 2015 at 16:09:46 UTC, Binarydepth wrote:
 		readf(" %d %d", &nam[0][num], &nam[1][num]);
 	}
 	foreach(nim; 0..num)	{
 		writef(" %d %d\n", &nam[0][num], &nam[1][num]);
Those indexes are backwards. And you really shouldn't need & on write. so try: readf(" %d %d", &nam[num][0], &nam[num][1]); and writef(" %d %d\n", nam[num][0], nam[num][1]);
Jul 28 2015
parent "Binarydepth" <binarydepth gmail.com> writes:
On Tuesday, 28 July 2015 at 16:12:28 UTC, Adam D. Ruppe wrote:
 On Tuesday, 28 July 2015 at 16:09:46 UTC, Binarydepth wrote:
 		readf(" %d %d", &nam[0][num], &nam[1][num]);
 	}
 	foreach(nim; 0..num)	{
 		writef(" %d %d\n", &nam[0][num], &nam[1][num]);
Those indexes are backwards. And you really shouldn't need & on write. so try: readf(" %d %d", &nam[num][0], &nam[num][1]); and writef(" %d %d\n", nam[num][0], nam[num][1]);
I declared : int[2][] nam; For real it is backwards ? nam[0][num]
Jul 28 2015
prev sibling parent reply "anonymous" <a b.cd> writes:
On Tuesday, 28 July 2015 at 16:09:46 UTC, Binarydepth wrote:
 Here is what I'm trying to do :

 import std.stdio : readf, writef;
 void main()	{
 	int[2][] nam;
 	int num;
 	readf(" %d", &num);
 	nam.length = num;
 	foreach(nim; 0..num)	{
 		readf(" %d %d", &nam[0][num], &nam[1][num]);
 	}
 	foreach(nim; 0..num)	{
 		writef(" %d %d\n", &nam[0][num], &nam[1][num]);
 	}
 }
In addition to Adam: there are typos (num instead of nim) - since num is the array length and the indices are 0-based, num is out of bounds... foreach(nim; 0..num) { readf(" %d %d", &nam[nim][0], &nam[nim][1]); } foreach(nim; 0..num) { writef(" %d %d\n", nam[nim][0], nam[nim][1]); } works fine.
Jul 28 2015
next sibling parent "Binarydepth" <binarydepth gmail.com> writes:
On Tuesday, 28 July 2015 at 16:24:39 UTC, anonymous wrote:
 On Tuesday, 28 July 2015 at 16:09:46 UTC, Binarydepth wrote:
 Here is what I'm trying to do :

 import std.stdio : readf, writef;
 void main()	{
 	int[2][] nam;
 	int num;
 	readf(" %d", &num);
 	nam.length = num;
 	foreach(nim; 0..num)	{
 		readf(" %d %d", &nam[0][num], &nam[1][num]);
 	}
 	foreach(nim; 0..num)	{
 		writef(" %d %d\n", &nam[0][num], &nam[1][num]);
 	}
 }
In addition to Adam: there are typos (num instead of nim) - since num is the array length and the indices are 0-based, num is out of bounds... foreach(nim; 0..num) { readf(" %d %d", &nam[nim][0], &nam[nim][1]); } foreach(nim; 0..num) { writef(" %d %d\n", nam[nim][0], nam[nim][1]); } works fine.
Damn! my first typo! Thanks :D
Jul 28 2015
prev sibling parent reply "Binarydepth" <binarydepth gmail.com> writes:
On Tuesday, 28 July 2015 at 16:24:39 UTC, anonymous wrote:
 On Tuesday, 28 July 2015 at 16:09:46 UTC, Binarydepth wrote:
 Here is what I'm trying to do :

 import std.stdio : readf, writef;
 void main()	{
 	int[2][] nam;
 	int num;
 	readf(" %d", &num);
 	nam.length = num;
 	foreach(nim; 0..num)	{
 		readf(" %d %d", &nam[0][num], &nam[1][num]);
 	}
 	foreach(nim; 0..num)	{
 		writef(" %d %d\n", &nam[0][num], &nam[1][num]);
 	}
 }
In addition to Adam: there are typos (num instead of nim) - since num is the array length and the indices are 0-based, num is out of bounds... foreach(nim; 0..num) { readf(" %d %d", &nam[nim][0], &nam[nim][1]); } foreach(nim; 0..num) { writef(" %d %d\n", nam[nim][0], nam[nim][1]); } works fine.
It works with 2 as input but shows error when number is 3 :(
Jul 28 2015
parent reply "anonymous" <a b.cd> writes:
On Tuesday, 28 July 2015 at 16:41:40 UTC, Binarydepth wrote:
 It works with 2 as input but shows error when number is 3 :(
I can't reproduce that or I misunderstood something: $ cat a.d import std.stdio : readf, writef; void main() { int[2][] nam; int num; readf(" %d", &num); nam.length = num; foreach(nim; 0..num) { readf(" %d %d", &nam[nim][0], &nam[nim][1]); } foreach(nim; 0..num) { writef(" %d %d\n", nam[nim][0], nam[nim][1]); } } $ dmd a.d $ ./a 3 1 2 3 4 5 6 1 2 3 4 5 6
Jul 28 2015
parent reply "Binarydepth" <binarydepth gmail.com> writes:
On Tuesday, 28 July 2015 at 16:53:35 UTC, anonymous wrote:
 On Tuesday, 28 July 2015 at 16:41:40 UTC, Binarydepth wrote:
 It works with 2 as input but shows error when number is 3 :(
I can't reproduce that or I misunderstood something: $ cat a.d import std.stdio : readf, writef; void main() { int[2][] nam; int num; readf(" %d", &num); nam.length = num; foreach(nim; 0..num) { readf(" %d %d", &nam[nim][0], &nam[nim][1]); } foreach(nim; 0..num) { writef(" %d %d\n", nam[nim][0], nam[nim][1]); } } $ dmd a.d $ ./a 3 1 2 3 4 5 6 1 2 3 4 5 6
Your code works but I don't understand why this has to go backwards. But well I don't know how "nam.length = num;" works My confusion comes because I declare "int[2][]" and then I use it backwards
Jul 28 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/28/15 12:59 PM, Binarydepth wrote:

 My confusion comes because I declare "int[2][]" and then I use it backwards
This can definitely be confusing. The way array types work in D is that they are of the form Type[]. This means that the element of Type[] is Type. When Type is actually another array, then you have a multi-indexed array. So in your case, "Type" is "int[2]". This means, each element of the dynamic array is a 2-element fixed-sized array. When indexing, it always goes out to in. So nam[0] is the first element of type int[2], and nam[0][0] is the first integer in that first element. Hope this helps. While confusing, it's also VERY consistent and logical. -Steve
Jul 28 2015
parent reply "Binarydepth" <binarydepth gmail.com> writes:
On Tuesday, 28 July 2015 at 17:07:47 UTC, Steven Schveighoffer 
wrote:
 On 7/28/15 12:59 PM, Binarydepth wrote:
 When indexing, it always goes out to in. So nam[0] is the first 
 element of type int[2], and nam[0][0] is the first integer in 
 that first element.
 -Steve
I don't get what you mean here. In general I understood that in D multidimensional arrays are a group of arrays.
Jul 28 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/28/15 1:26 PM, Binarydepth wrote:
 On Tuesday, 28 July 2015 at 17:07:47 UTC, Steven Schveighoffer wrote:
 On 7/28/15 12:59 PM, Binarydepth wrote:
 When indexing, it always goes out to in. So nam[0] is the first
 element of type int[2], and nam[0][0] is the first integer in that
 first element.
I don't get what you mean here. In general I understood that in D multidimensional arrays are a group of arrays.
What I mean is the first index operation operates on the entire type. The second one operates on the element that the first retrieved, and so on. -Steve
Jul 28 2015
parent reply "Binarydepth" <binarydepth gmail.com> writes:
On Tuesday, 28 July 2015 at 17:34:46 UTC, Steven Schveighoffer 
wrote:
 On 7/28/15 1:26 PM, Binarydepth wrote:
 On Tuesday, 28 July 2015 at 17:07:47 UTC, Steven Schveighoffer 
 wrote:
 On 7/28/15 12:59 PM, Binarydepth wrote:
 When indexing, it always goes out to in. So nam[0] is the 
 first
 element of type int[2], and nam[0][0] is the first integer in 
 that
 first element.
I don't get what you mean here. In general I understood that in D multidimensional arrays are a group of arrays.
What I mean is the first index operation operates on the entire type. The second one operates on the element that the first retrieved, and so on. -Steve
I'm reading the reference : http://dlang.org/arrays.html And I'm declaring two dynamic arrays as I understand. What I had in mind was declaring a dynamic array of two elements each.
Jul 28 2015
parent reply "anonymous" <a b.cd> writes:
On Tuesday, 28 July 2015 at 22:52:31 UTC, Binarydepth wrote:
 I'm reading the reference : http://dlang.org/arrays.html

 And I'm declaring two dynamic arrays as I understand. What I 
 had in mind was declaring a dynamic array of two elements each.
int[2][] is exactly an dynamic array of (arrays with the length 2), the logic behind this notation is: 1. Array of 2 int -> int[2] 2. a dynamic array of 1. -> int[2][] (like SomeType[] is an array of SomeType) If you define SomeType e.g. as struct SomeType { int firstElement; int secondElement; } you get something similar. Yes, this is different from e.g. Java, where new int[2][42] creates an array of 2 arrays with 42 elements each. Accessing int[2][] nums : 1. nums[5] is the 5th element of nums which is of type int[2] 2. nums[5][0] is the zeroth element of 5th element of nums int[2] tmp = nums[5]; int value = tmp[0]; does the same...
Jul 29 2015
parent "Binarydepth" <binarydepth gmail.com> writes:
On Wednesday, 29 July 2015 at 08:03:06 UTC, anonymous wrote:
 int[2][] is exactly an dynamic array of (arrays with the length 
 2), the logic behind this notation is:
 1. Array of 2 int -> int[2]
 2. a dynamic array of 1. -> int[2][] (like SomeType[] is an 
 array of SomeType)
Thank you!
Jul 29 2015
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/28/2015 10:26 AM, Binarydepth wrote:

 In general I understood that in D
 multidimensional arrays are a group of arrays.
The confusion comes from the fact that D does not have multidimensional arrays. (Neither C and nor C++.) The array syntax is simple. Definition: Type[] name; Indexing: name[i]; Done... :) Yes, 'Type' can be an array but that does not change anything. Ali
Jul 28 2015
prev sibling parent reply "CraigDillabaugh" <craig.dillabaugh gmail.com> writes:
On Tuesday, 28 July 2015 at 17:26:39 UTC, Binarydepth wrote:
 On Tuesday, 28 July 2015 at 17:07:47 UTC, Steven Schveighoffer 
 wrote:
 On 7/28/15 12:59 PM, Binarydepth wrote:
 When indexing, it always goes out to in. So nam[0] is the 
 first element of type int[2], and nam[0][0] is the first 
 integer in that first element.
 -Steve
I don't get what you mean here. In general I understood that in D multidimensional arrays are a group of arrays.
A bit off-topic. I've done a lot of image processing work that deals with 2D arrays in particular. I must admit that for the most part now I just use a 1D array for all my 2D arrays and do a bit of index arithmetic to figure the location in 2D. To index I have to do something like (for row major order): my2darray[row * COLS_PER_ROW + col] = blah; But I find this has many advantages: 1. The tiny bit of arithmetic is more than offset by not having to deal with trying to remember the order of the indices. 2. You can chose if you want row or column major order. 3. It makes lots of operations much easier, ie. adding two images together if they are of the same dimensions, generating histograms, calculating the average value in a 2D array. 4. Easy to set size dynamically. 5. Consistent between pretty much every programming language (ie. my C and D code would look the same). 6. (IMHO) Code is actually more readable. But then I find lots of brackets confusing ... so maybe its just me.
Jul 28 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/28/15 3:33 PM, CraigDillabaugh wrote:

 6. (IMHO) Code is actually more readable.  But then I find lots of
 brackets confusing ... so maybe its just me.
Have you considered a wrapper that uses multi-dimensional access? i.e.: my2darray[row, col] = blah; -Steve
Jul 28 2015
parent "CraigDillabaugh" <craig.dillabaugh gmail.com> writes:
On Tuesday, 28 July 2015 at 20:07:12 UTC, Steven Schveighoffer 
wrote:
 On 7/28/15 3:33 PM, CraigDillabaugh wrote:

 6. (IMHO) Code is actually more readable.  But then I find 
 lots of
 brackets confusing ... so maybe its just me.
Have you considered a wrapper that uses multi-dimensional access? i.e.: my2darray[row, col] = blah; -Steve
It has crossed my mind, but I've got so used to doing the position calculations I haven't yet tried it. I guess you would simply need to put your array in a struct and overload the '[]' operator correct? (Plus the appropriate constructors, etc).
Jul 28 2015
prev sibling parent "Binarydepth" <binarydepth gmail.com> writes:
On Friday, 24 July 2015 at 15:26:27 UTC, Adam D. Ruppe wrote:
 On Friday, 24 July 2015 at 15:22:15 UTC, Binarydepth wrote:
 I want to use memory based on user input. In this case declare 
 a bi-dimensional array (int[2][var]), var being the user input.
Declare: int[2][] your_array; your_array.length = var; The runtime will handle the dynamic memory allocation for you when you set the length on a slice.
Ok, Sorry I was declaring the array in C style also. It compiled after chaging it. :D TY
Jul 24 2015