Re: Help on array pointers

2023-09-22 Thread Joe--- via Digitalmars-d-learn

On Monday, 18 September 2023 at 02:49:37 UTC, vino wrote:

On Sunday, 17 September 2023 at 18:28:36 UTC, Joe wrote:

On Friday, 15 September 2023 at 16:55:34 UTC, Vino wrote:

[...]



[...]



char[] invalid = (cast(char*)malloc(char.sizeof * 
len))[0..len];


This is not the way to go about it. You are mixing "pointer 
arrays" with "arrays".


[...]


Thank you very much, I am still newbie for programming and 
currently concentrating on Arrays/Struct/Pointers/Memory 
management.


It will make more sense over time. It's actually really simple 
but it takes time to get used to thinking along the lines of the 
computer languages and such.


My suggestion is simply do a lot of examples. Just type them in. 
As you type you think about what you are typing and how it 
relates. Then you will start to notice the patterns and such.


I wouldn't try to create new programs from scratch because it's 
easy to make mistakes that can be very hard to debug.


D might not be the best language to start learning programming.

E.g., might be better to go with javascript, lua, or python and 
get a nice rapid development environment. Even though D is fast 
to compile it's not that fast.


Maybe use Repl which lets you code line by line essentially. All 
languages more or less are the same but just look different so it 
you want to find out one that has the most convenience. you don't 
want to bite off too much as it will slow you down.


Ultimately it's just like anything else though in that you are 
learning a language and all it's nuances. You ultimately have to 
learn how to translate your thoughts and desires in to the 
correct syntax so you can make the language useful and act as a 
tool. If you try to us it as a tool before you learn to mimic 
others it will be very slow and frustrating.



Because most languages are 99% the same with just different 
syntax(just about every major programming language can do what 
ever other one can, it's just some are better/easier at doing 
certain things than others).


You might try learning several languages at once as it can 
actually speed things up.


Learn how to write simple programs(hello worlds) then modify 
those to do more and then learn control 
structures(branching(if's), loops(for)), variables, etc. Build up 
slowly and everything will make sense. Build up fast and you'll 
get lost at some point and then spend a lot of time trying to 
figure out how to make sense of it.


Ideally you want an ide and language that gives you precise info 
on errors that you make else it can be hard to track down 
mistakes because sometimes errors can be hidden. D is not good 
for.


Even Q-basis might be better to start with or try to find Turbo 
Pascal if it still exists.


What makes D great is it's generic/template programming and that 
is a more complex topic that you probably won't get much in to 
for a few years(although it is not really hard it will seem like 
it at first).


D has a lot of features that hard core programmers like and so 
you are not going to be using those features for a while so it 
might not be worth using D to learn off of.


Not saying you can't do it but it might be slow. You could always 
do it in parallel. E.g., learn to write simple programs in many 
languages then build up.


E.g.,

for i=1:10 // Matlab
for(auto i = 1; i < 10; i++)  // D
for(int i = 1; i < 10; i++)  // C
for(var i = 1; i < 10; i++)  // JS
for i from 1 to 10 // maple
loop(50, ...) // JSFX
for i = 1,10 // lua

etc.

The underlying idea is that one wants a way to do the same thing 
over and over and so loops exist to handle that pattern. Each 
language uses different ways to express a loop. Just like 
languages, all languages uses nouns, verbs, etc but express them 
differently.





Re: Help on array pointers

2023-09-17 Thread vino via Digitalmars-d-learn

On Sunday, 17 September 2023 at 18:28:36 UTC, Joe wrote:

On Friday, 15 September 2023 at 16:55:34 UTC, Vino wrote:

[...]



[...]



char[] invalid = (cast(char*)malloc(char.sizeof * len))[0..len];

This is not the way to go about it. You are mixing "pointer 
arrays" with "arrays".


[...]


Thank you very much, I am still newbie for programming and 
currently concentrating on Arrays/Struct/Pointers/Memory 
management.


Re: Help on array pointers

2023-09-17 Thread Joe--- via Digitalmars-d-learn

On Friday, 15 September 2023 at 16:55:34 UTC, Vino wrote:

On Friday, 15 September 2023 at 15:27:00 UTC, Vino wrote:

On Friday, 15 September 2023 at 02:25:09 UTC, Joe wrote:

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

[...]


A pointer is a type that points to something. It's literally 
that simple. Every piece of data and code exist somewhere in 
memory. Every piece of memory has an address. The address is 
what a pointer contains. Sometimes we want a type that is the 
address itself rather than a value/number.


[...]


Hi Joe,
Thank you very much for the explanation can you please correct 
me if my understanding is incorrect

```
byte[] z; // Creates an array of bytes. That is, the compiler 
will create a pointer to an array of memory and track it's 
length and deal with memory allocation and all that.

```
If we use the above method then :


The compiler takes care of initilizing the array and free the 
memory after the usage.

And this is the recommended method.

```
We can use a pointer as an array also, this is the "old school 
way of creating arrays".

int qlen = 5;
int* q = cast(int*)malloc(int.sizeof*qlen);
``` 
If we use the above method then :
We need to manual initilize the array.
Ensure that the memory is freed after the usage using 
try/final block.


By default the memory allocation for arrays in D is based on 
GC (expect for std.array containers) if we want to 
reduce/avoid GC then we need to use the old school way of 
creating the arrays.


In case of using the old school ways then can you guide me 
what is wrong in my earlier code that I am getting the below 
error and how do I correct the same.


Error
```
Invalid Name passed: /T
double free or corruption (out)
Error: program killed by signal 6
```


Hi All,

 At last was able to resolve the issue, but not sure 
whether this is the reight solution.


Code:
```
import std.stdio: writeln;
import std.exception: enforce;
import std.range: empty;
import std.format: format;

auto ref testNames(in string[] names) {
  enforce(!empty(names), "Names cannot be Empty or Null");

 import core.stdc.stdlib;
 import std.algorithm: any, canFind;

 string[] _names;
 size_t len = 19;
 char[] invalid = (cast(char*)malloc(char.sizeof * 
len))[0..len];

 invalid[0 ..len] = 0; //Array Initlization

 try {
   version(Posix) {
  invalid = 
['\'','\"',':',';','*','&','/','[',']','-','+','$','#','<','>','{','}','(',')'];

  }

  foreach(i; names.dup) {
  auto result = i.any!(a => invalid.canFind(a));
  if(result) { throw new Exception("Invalid Name 
passed: %s".format(i)); }

  else {_names = names.dup; return _names; }
  }
} catch(Exception e) { writeln(e.msg);  }
  finally { invalid = null; free(invalid.ptr); } // 
added invalid = null resolved the issue

 return _names;
}

void main () {
writeln(testNames(["/T"]));
}

From,
Vino



char[] invalid = (cast(char*)malloc(char.sizeof * len))[0..len];

This is not the way to go about it. You are mixing "pointer 
arrays" with "arrays".


You are creating a pointer array then turning that in to an 
array. There is no need to do that. Basically you are copying 
what the compiler already does for you.


When you are using arrays([] language) you don't have to worry 
about anything. Just use them as arrays directly and let the 
compiler deal with memory management. The entire point of 
"managed arrays" is to avoid having to manually deal with memory 
which can cause problems if one is not careful.


Of course you have to make sure your array used used correctly 
but that should be obvious.




char[] invalid = (cast(char*)malloc(char.sizeof * len))[0..len];

is exactly the same as

char[] invalid. EXCEPT that you've forced it to be initialized 
with a length of len and went from D in to C then back to D just 
to create an array. You are making it much more complex than it 
needs to be. There are good tutorials on D arrays that you should 
look over. You will see how easy they are.


You could just do char[] invalid = new char[](len); for the same 
effect but is nicer. New understands char, malloc only 
understands bytes. You should not use malloc in D unless you 
explicitly know you need to use it. Malloc is primitive memory 
management.


When you use D's symantics for arrays it is much easier... which 
is the entire point. You don't even need to free the arrays. D 
knows they are local variable sand will free them when out of 
scope. It will grow them when they need to grow, etc.


invalid = null; free(invalid.ptr);

That does nothing. you set invalid.ptr to null and are freeing 
null so you are not freeing the array.


You don't have to though, the array will be free out of scope(not 
in final though so exceptions could cause memory leak) because it 
is a D array.


Do not 

Re: Help on array pointers

2023-09-15 Thread Vino via Digitalmars-d-learn

On Friday, 15 September 2023 at 15:27:00 UTC, Vino wrote:

On Friday, 15 September 2023 at 02:25:09 UTC, Joe wrote:

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

[...]


A pointer is a type that points to something. It's literally 
that simple. Every piece of data and code exist somewhere in 
memory. Every piece of memory has an address. The address is 
what a pointer contains. Sometimes we want a type that is the 
address itself rather than a value/number.


[...]


Hi Joe,
Thank you very much for the explanation can you please correct 
me if my understanding is incorrect

```
byte[] z; // Creates an array of bytes. That is, the compiler 
will create a pointer to an array of memory and track it's 
length and deal with memory allocation and all that.

```
If we use the above method then :
The compiler takes care of initilizing the array and free the 
memory after the usage.

And this is the recommended method.

```
We can use a pointer as an array also, this is the "old school 
way of creating arrays".

int qlen = 5;
int* q = cast(int*)malloc(int.sizeof*qlen);
``` 
If we use the above method then :
We need to manual initilize the array.
Ensure that the memory is freed after the usage using try/final 
block.


By default the memory allocation for arrays in D is based on GC 
(expect for std.array containers) if we want to reduce/avoid GC 
then we need to use the old school way of creating the arrays.


In case of using the old school ways then can you guide me what 
is wrong in my earlier code that I am getting the below error 
and how do I correct the same.


Error
```
Invalid Name passed: /T
double free or corruption (out)
Error: program killed by signal 6
```


Hi All,

 At last was able to resolve the issue, but not sure whether 
this is the reight solution.


Code:
```
import std.stdio: writeln;
import std.exception: enforce;
import std.range: empty;
import std.format: format;

auto ref testNames(in string[] names) {
  enforce(!empty(names), "Names cannot be Empty or Null");

 import core.stdc.stdlib;
 import std.algorithm: any, canFind;

 string[] _names;
 size_t len = 19;
 char[] invalid = (cast(char*)malloc(char.sizeof * 
len))[0..len];

 invalid[0 ..len] = 0; //Array Initlization

 try {
   version(Posix) {
  invalid = 
['\'','\"',':',';','*','&','/','[',']','-','+','$','#','<','>','{','}','(',')'];

  }

  foreach(i; names.dup) {
  auto result = i.any!(a => invalid.canFind(a));
  if(result) { throw new Exception("Invalid Name passed: 
%s".format(i)); }

  else {_names = names.dup; return _names; }
  }
} catch(Exception e) { writeln(e.msg);  }
  finally { invalid = null; free(invalid.ptr); } // added 
invalid = null resolved the issue

 return _names;
}

void main () {
writeln(testNames(["/T"]));
}

From,
Vino


Re: Help on array pointers

2023-09-15 Thread Vino via Digitalmars-d-learn

On Friday, 15 September 2023 at 02:25:09 UTC, Joe wrote:

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

[...]


A pointer is a type that points to something. It's literally 
that simple. Every piece of data and code exist somewhere in 
memory. Every piece of memory has an address. The address is 
what a pointer contains. Sometimes we want a type that is the 
address itself rather than a value/number.


[...]


Hi Joe,
Thank you very much for the explanation can you please correct me 
if my understanding is incorrect

```
byte[] z; // Creates an array of bytes. That is, the compiler 
will create a pointer to an array of memory and track it's length 
and deal with memory allocation and all that.

```
If we use the above method then :
The compiler takes care of initilizing the array and free the 
memory after the usage.

And this is the recommended method.

```
We can use a pointer as an array also, this is the "old school 
way of creating arrays".

int qlen = 5;
int* q = cast(int*)malloc(int.sizeof*qlen);
``` 
If we use the above method then :
We need to manual initilize the array.
Ensure that the memory is freed after the usage using try/final 
block.


By default the memory allocation for arrays in D is based on GC 
(expect for std.array containers) if we want to reduce/avoid GC 
then we need to use the old school way of creating the arrays.


In case of using the old school ways then can you guide me what 
is wrong in my earlier code that I am getting the below error and 
how do I correct the same.


Error
```
Invalid Name passed: /T
double free or corruption (out)
Error: program killed by signal 6
```



Re: Help on array pointers

2023-09-14 Thread Joe--- via Digitalmars-d-learn

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

Hi All,

   Request your help to guide me in understanding about 
pointers, the below code works,I have few question which i need 
your help for better understanding.


Questions:1
```
char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
The above statement allocate memory for char type and the size 
of the allocated memory is char.sizeof * length so what is the 
use of this "[0..length]";


Question:2
```
char[]* invalidptr = 
```
Is this the right way to create a array pointer.

Question: 3
```
ST1: char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];
ST2: char[]* invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
What is the difference between the above to statement.

Question: 4
Who do we free the memory allocated.
Code:
```
auto ref testNames(in string[] names) {
enforce(!empty(names), "Names cannot be Empty or Null");

import core.stdc.stdlib;
import std.algorithm: any, canFind;

size_t length = 20;
	char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

char[]* invalidptr = 

	version(Windows) { (*invalidptr) = 
['\'','\"',':',';','*','&','[',']','-','+','$','#','<','>','{','}','(',')']; }


foreach(i; names.dup) {
auto result = i.any!(a => (*invalidptr).canFind(a));
		if(result) { throw new Exception("Invalid Name passed: 
%s".format(i)); }

}
string[] _names = names.dup;
return _names;
}
```
From,
Vino


A pointer is a type that points to something. It's literally that 
simple. Every piece of data and code exist somewhere in memory. 
Every piece of memory has an address. The address is what a 
pointer contains. Sometimes we want a type that is the address 
itself rather than a value/number.


https://run.dlang.io/gist/19c63d325ee412df23bdbefabce111b9



import std, std.stdio, core.stdc.stdlib;


void main()
{
   	float x = 43.534f;  // Creates a float type that hold 
sthe value 43.534

writeln("Value of x = ", x); // Displays it's value
writeln("Address of x = ", ); // Displays it's address

writeln();
float* y = null; // creates a pointer of type float note 
that it is point to no memory location(null) and so it is an 
error to store a value to the location


writeln("Value of y = ", y); // Displays it's 
address(remember, y is a ptr to a float, not a float)


y = new float(); // This allocates free/unused memory(of 
float type) to y so we can store a value.
*y = 50.34f; // assigns it the value 50.34. We have to 
use * because if we didn't we would be trying to change the 
address of y


writeln("Value of y = ", y); // Displays it's 
address(remember, y is a ptr to a float, not a float)
writeln("Address of y = ", ); // Writes it's address(y 
is a pointer but it also is stored in a location in memory and 
hence has an address
writeln("Dereferenced value of y = ", *y); // Displays 
the value y is pointing to interpreting it as a float(the base 
type of the pointer)


writeln("Dereferences the value of y as if it were an int 
= ", *(cast(int*)y)); // Displays the value y is pointing to 
interpreting it as a int. We have to force the compilier to 
reinterpret it as an int*.


writeln();
byte[] z; // Creates an array of bytes. That is, the 
compiler will create a pointer to an array of memory and track 
it's length and deal with memory allocation and all that.


writeln("Value of z = ", z); // Displays it's 
address(remember, z is a ptr to a float, not a float)
writeln("Address of z = ", ); // Note that z is an 
array but it is a pointer to and  gets the address where the 
"array" is stored.
writeln("Value of z's pointer = ", z.ptr); // Displays 
it's address(remember, y is a ptr to a float, not a float)
writeln("Length of z = ", z.length); // Writes it's 
address(y is a pointer but it also is stored in a location in 
memory and hence has an address


writeln();

z ~= 4; // We can store/append a value to our array. The 
compiler will take care of dealing with allocating memory and all 
that.
writeln("Value of z = ", z); // Displays it's 
address(remember, z is a ptr to a float, not a float)
writeln("Address of z = ", ); // Note that z is an 
array but it is a pointer to and  gets the address where the 
"array" is stored.
writeln("Value of z's pointer = ", z.ptr); // Displays 
it's address(remember, y is a ptr to a float, not a float)
writeln("Length of z = ", z.length); // Writes it's 
address(y is a pointer but it also is stored in a location in 
memory and hence has an address


z ~= 54; // We can store/append a value to our array. The 
compiler will take 

Re: Help on array pointers

2023-09-14 Thread vino via Digitalmars-d-learn

On Thursday, 14 September 2023 at 17:23:53 UTC, Vino wrote:
On Thursday, 14 September 2023 at 15:33:45 UTC, Paul Backus 
wrote:

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

Questions:1
```
char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
The above statement allocate memory for char type and the 
size of the allocated memory is char.sizeof * length so what 
is the use of this "[0..length]";


The difference between a `char*` and a `char[]` is that the 
`char[]` includes both the pointer and the length in the same 
variable. The slicing operator `[0 .. length]` is used to 
combine the pointer and the length into a single `char[]` 
variable.


Strictly speaking, you don't *have* to do this--you could 
leave the pointer and the length in separate variables, and 
the program would still work. Most D programmers prefer to 
combine them because it's more convenient and less error-prone 
(for example, it makes it much harder to accidentally use the 
wrong length).



Question:2
```
char[]* invalidptr = 
```
Is this the right way to create a array pointer.


It depends on what you mean by "array pointer".

A `char[]` contains a pointer and a length. A `char[]*` is a 
pointer to a thing that contains a pointer and a length. In 
order to get from a `char[]*` to the actual `char` data, you 
have to follow *two* pointers. In that sense, you can think of 
`char[]*` in D as similar to `char**` in C.



Question: 3
```
ST1: char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];
ST2: char[]* invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
What is the difference between the above to statement.


The first statement is valid code and the second one isn't.


Question: 4
Who do we free the memory allocated.
Code:
[...]


In order to ensure that the memory is freed correctly even 
when an exception is thrown, you can use a [`try`/`finally` 
block.][1]


char[] a = (cast(char*) malloc(char.sizeof * length))[0 .. 
length];


try {
doSomethingWith(a);
} finally {
  free(a.ptr);
}

However, this by itself will not fix the code in your example 
because it has another serious mistake: it does not initialize 
the memory allocated by `malloc`. Attempting to read from 
uninitialized memory results in [undefined behavior][2], which 
may cause your program to crash or behave unpredictably.


[1]: 
http://ddili.org/ders/d.en/exceptions.html#ix_exceptions.try

[2]: https://c-faq.com/ansi/undef.html


Hi Pual,

   Thank you very much for the explanation, based on your 
statement i modifiyed the code as below, and now ti dose not 
throw the exception where it should throw exception


Code:
```
import std.stdio: writeln;
import std.exception: enforce;
import std.range: empty;
import std.format: format;
auto ref testNames(in string[] names) {
enforce(!empty(names), "Names cannot be Empty or Null");

import core.stdc.stdlib;
import std.algorithm: any, canFind;

string[] _names;
size_t length = 20;
	char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

invalid[0 ..length] = 0;

try
{
			version(Windows) { invalid = 
['\'','\"',':',';','*','&','[',']','-','+','$','#','<','>','{','}','(',')']; }

foreach(i; names.dup) {
auto result = i.any!(a => invalid.canFind(a));
if(result) { throw new Exception("Invalid Name passed: 
%s".format(i)); }

 }
}   catch(Exception e) { writeln(e.msg);  }
finally { free(invalid.ptr);  }
_names = names.dup;
return _names;
}

void main () {
writeln(testNames(["/T"]));
}
```


Hi All,

 Was able to find out the issue, and now it is throwing both 
the exception and another error message as below 
https://run.dlang.io/is/VZeOOj


Error:
```
Invalid Name passed: /T
double free or corruption (out)
Error: program killed by signal 6
```

Code:
```
import std.stdio: writeln;
import std.exception: enforce;
import std.range: empty;
import std.format: format;

auto ref testNames(in string[] names) {
enforce(!empty(names), "Names cannot be Empty or Null");

import core.stdc.stdlib;
import std.algorithm: any, canFind;

string[] _names;
size_t length = 20;
	char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

invalid[0 ..length] = 0;

try
{
			invalid = 
['\'','\"',':',';','*','&','[',']','-','+','$','#','<','>','{','}','(',')'];

foreach(i; names.dup) {
auto result = i.any!(a => invalid.canFind(a));
if(result) { throw new Exception("Invalid Name passed: 

Re: Help on array pointers

2023-09-14 Thread Vino via Digitalmars-d-learn

On Thursday, 14 September 2023 at 15:33:45 UTC, Paul Backus wrote:

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

Questions:1
```
char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
The above statement allocate memory for char type and the size 
of the allocated memory is char.sizeof * length so what is the 
use of this "[0..length]";


The difference between a `char*` and a `char[]` is that the 
`char[]` includes both the pointer and the length in the same 
variable. The slicing operator `[0 .. length]` is used to 
combine the pointer and the length into a single `char[]` 
variable.


Strictly speaking, you don't *have* to do this--you could leave 
the pointer and the length in separate variables, and the 
program would still work. Most D programmers prefer to combine 
them because it's more convenient and less error-prone (for 
example, it makes it much harder to accidentally use the wrong 
length).



Question:2
```
char[]* invalidptr = 
```
Is this the right way to create a array pointer.


It depends on what you mean by "array pointer".

A `char[]` contains a pointer and a length. A `char[]*` is a 
pointer to a thing that contains a pointer and a length. In 
order to get from a `char[]*` to the actual `char` data, you 
have to follow *two* pointers. In that sense, you can think of 
`char[]*` in D as similar to `char**` in C.



Question: 3
```
ST1: char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];
ST2: char[]* invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
What is the difference between the above to statement.


The first statement is valid code and the second one isn't.


Question: 4
Who do we free the memory allocated.
Code:
[...]


In order to ensure that the memory is freed correctly even when 
an exception is thrown, you can use a [`try`/`finally` 
block.][1]


char[] a = (cast(char*) malloc(char.sizeof * length))[0 .. 
length];


try {
doSomethingWith(a);
} finally {
  free(a.ptr);
}

However, this by itself will not fix the code in your example 
because it has another serious mistake: it does not initialize 
the memory allocated by `malloc`. Attempting to read from 
uninitialized memory results in [undefined behavior][2], which 
may cause your program to crash or behave unpredictably.


[1]: 
http://ddili.org/ders/d.en/exceptions.html#ix_exceptions.try

[2]: https://c-faq.com/ansi/undef.html


Hi Pual,

   Thank you very much for the explanation, based on your 
statement i modifiyed the code as below, and now ti dose not 
throw the exception where it should throw exception


Code:
```
import std.stdio: writeln;
import std.exception: enforce;
import std.range: empty;
import std.format: format;
auto ref testNames(in string[] names) {
enforce(!empty(names), "Names cannot be Empty or Null");

import core.stdc.stdlib;
import std.algorithm: any, canFind;

string[] _names;
size_t length = 20;
	char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

invalid[0 ..length] = 0;

try
{
			version(Windows) { invalid = 
['\'','\"',':',';','*','&','[',']','-','+','$','#','<','>','{','}','(',')']; }

foreach(i; names.dup) {
auto result = i.any!(a => invalid.canFind(a));
if(result) { throw new Exception("Invalid Name passed: 
%s".format(i)); }

 }
}   catch(Exception e) { writeln(e.msg);  }
finally { free(invalid.ptr);  }
_names = names.dup;
return _names;
}

void main () {
writeln(testNames(["/T"]));
}
```



Re: Help on array pointers

2023-09-14 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

Questions:1
```
char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
The above statement allocate memory for char type and the size 
of the allocated memory is char.sizeof * length so what is the 
use of this "[0..length]";


The difference between a `char*` and a `char[]` is that the 
`char[]` includes both the pointer and the length in the same 
variable. The slicing operator `[0 .. length]` is used to combine 
the pointer and the length into a single `char[]` variable.


Strictly speaking, you don't *have* to do this--you could leave 
the pointer and the length in separate variables, and the program 
would still work. Most D programmers prefer to combine them 
because it's more convenient and less error-prone (for example, 
it makes it much harder to accidentally use the wrong length).



Question:2
```
char[]* invalidptr = 
```
Is this the right way to create a array pointer.


It depends on what you mean by "array pointer".

A `char[]` contains a pointer and a length. A `char[]*` is a 
pointer to a thing that contains a pointer and a length. In order 
to get from a `char[]*` to the actual `char` data, you have to 
follow *two* pointers. In that sense, you can think of `char[]*` 
in D as similar to `char**` in C.



Question: 3
```
ST1: char[] invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];
ST2: char[]* invalid = (cast(char*)malloc(char.sizeof * 
length))[0..length];

```
What is the difference between the above to statement.


The first statement is valid code and the second one isn't.


Question: 4
Who do we free the memory allocated.
Code:
[...]


In order to ensure that the memory is freed correctly even when 
an exception is thrown, you can use a [`try`/`finally` block.][1]


char[] a = (cast(char*) malloc(char.sizeof * length))[0 .. 
length];


try {
doSomethingWith(a);
} finally {
  free(a.ptr);
}

However, this by itself will not fix the code in your example 
because it has another serious mistake: it does not initialize 
the memory allocated by `malloc`. Attempting to read from 
uninitialized memory results in [undefined behavior][2], which 
may cause your program to crash or behave unpredictably.


[1]: http://ddili.org/ders/d.en/exceptions.html#ix_exceptions.try
[2]: https://c-faq.com/ansi/undef.html