Lazarus

Free Pascal => Beginners => Topic started by: Weeb mindset on August 08, 2020, 05:05:17 pm

Title: Help about dynamic array function
Post by: Weeb mindset on August 08, 2020, 05:05:17 pm
Here is my code, the expected input is 'n_n_n', where n is integer.
And error occurred at line
Code: Pascal  [Select][+][-]
  1. if s[u] = '_' then begin val(s[u],ti,spec_i); max_s_to_a_of_int[u] := ti; inc(len,1); end;
  2.  
raised exception class 'Esternal: SIGSEGV'.
No idea where is wrong.

#edit, This is my first time posting, thanks to everyone pointing out the mistakes !
int_a is declared as array of integer.

Code: Pascal  [Select][+][-]
  1. function max_s_to_a_of_int(s:string):int_a;
  2. var
  3.     len,u,ti : integer;
  4.     spec_i   : integer;
  5. begin
  6.      len := 0;
  7.      for u := 1 to length(s) do
  8.          if s[u] = '_' then begin val(s[u],ti,spec_i); max_s_to_a_of_int[u] := ti; inc(len,1); end;
  9.      setlength(max_s_to_a_of_int,len);
  10.  
  11. end;    
 
Title: Re: Help about dynamic array function
Post by: Thaddy on August 08, 2020, 05:30:44 pm
Can you post real code instead of the above, because that annoys me and takes too much trouble to test...
Title: Re: Help about dynamic array function
Post by: TRon on August 08, 2020, 05:40:18 pm
Hi Weeb,

The forum software is 'eating' some stuff from your code because it is recognised and handled as a special tag for that software (such as underlining).

Always post code using code-tags, see https://wiki.freepascal.org/Forum#Use_code_tags

Here is my code, the expected input is 'n_n_n', where n is integer.
And error occurred at line'
Code: Pascal  [Select][+][-]
  1. if s[u] = '_' then begin val(s[u],ti,spec_i); max_s_to_a_of_int[u] := ti; inc(len,1); end;
  2.  
raised exception class 'Esternal: SIGSEGV'.
In addition to that, if you format/structure your code a little better then you are able to get a more precise indication where exactly the error occurs.

Code: Pascal  [Select][+][-]
  1. function max_s_to_a_of_int(s:string):int_a;
  2. var
  3.   len,u,ti : integer;
  4.   spec_i   : integer;
  5. begin
  6.   len := 0;
  7.   for u := 1 to length(s) do if s[u] = '_' then
  8.   begin
  9.     val(s[u],ti,spec_i);
  10.     max_s_to_a_of_int[u] := ti;
  11.     inc(len,1);
  12.   end;
  13.   setlength(max_s_to_a_of_int, len);
  14. end;
  15.  

Other than that, I seem to be missing some type declarations ? For those it is common to prefix them with a letter T (so "tint_a" instead of "int_a")

edit: that gives you a solid
Code: [Select]
./test
Runtime error 201 at $000102B0
  $000102B0  MAX_S_TO_A_OF_INT,  line 10 of test.pas

And that is because your dynamic array has no length while you do store an item in it. You seem to be doing that afterwards in your code.

The compiler gives a warning about that during compilation btw:
Code: [Select]
test.pas(10,22) Warning: function result variable of a managed type does not seem to be initialized
Title: Re: Help about dynamic array function
Post by: Thaddy on August 08, 2020, 06:00:24 pm
And that is because your dynamic array has no length while you do store an item in it. You seem to be doing that afterwards in your code.

The compiler gives a warning about that during compilation btw:
Code: [Select]
test.pas(10,22) Warning: function result variable of a managed type does not seem to be initialized
That is how far I came too, with some guess work. To access dynamic arrays you have to control its size first.
Title: Re: Help about dynamic array function
Post by: Bart on August 08, 2020, 06:12:58 pm
B.t.w if Val() fails, your code produces wrong results.

Bart
Title: Re: Help about dynamic array function
Post by: TRon on August 08, 2020, 06:14:19 pm
Indeed Thaddy.

I simply love it when a compiler is informative that way. It warns you about the error your code is about to make.... if only the compiler could fix that mistake automagically itself somehow .... :)

edit: fwiw variable "u" is used as index to both the string that is parsed as well as the returning dynamic array, which does not make a whole lot of sense imho. And Bart also has a valid point, and in addition what would happen if the provided 'n' inside a string would consist of more than 1 digit.
Title: Re: Help about dynamic array function
Post by: jamie on August 08, 2020, 09:06:25 pm
The fact that he's writing to what we assume is a array on the output before setting its size kind of tells the story..

Maybe it should be preset to a max size first then sized down before exiting the function ?
Title: Re: Help about dynamic array function
Post by: Thaddy on August 08, 2020, 09:07:51 pm
No. Minimum size. I.e. empty.
Title: Re: Help about dynamic array function
Post by: lucamar on August 08, 2020, 09:28:12 pm
Or count the number of "_" in the input and add one to set a probable size, check limits along the way and set the computed size a the end.

Lots of ways to cook a fish ... ;)
Title: Re: Help about dynamic array function
Post by: Weeb mindset on August 09, 2020, 08:37:21 am
Or count the number of "_" in the input and add one to set a probable size, check limits along the way and set the computed size a the end.

Lots of ways to cook a fish ... ;)

Got it, Thanks !
Title: Re: Help about dynamic array function
Post by: Weeb mindset on August 09, 2020, 08:39:10 am
Hi Weeb,

The forum software is 'eating' some stuff from your code because it is recognised and handled as a special tag for that software (such as underlining).

Always post code using code-tags, see https://wiki.freepascal.org/Forum#Use_code_tags

Here is my code, the expected input is 'n_n_n', where n is integer.
And error occurred at line'
Code: Pascal  [Select][+][-]
  1. if s[u] = '_' then begin val(s[u],ti,spec_i); max_s_to_a_of_int[u] := ti; inc(len,1); end;
  2.  
raised exception class 'Esternal: SIGSEGV'.
In addition to that, if you format/structure your code a little better then you are able to get a more precise indication where exactly the error occurs.

Code: Pascal  [Select][+][-]
  1. function max_s_to_a_of_int(s:string):int_a;
  2. var
  3.   len,u,ti : integer;
  4.   spec_i   : integer;
  5. begin
  6.   len := 0;
  7.   for u := 1 to length(s) do if s[u] = '_' then
  8.   begin
  9.     val(s[u],ti,spec_i);
  10.     max_s_to_a_of_int[u] := ti;
  11.     inc(len,1);
  12.   end;
  13.   setlength(max_s_to_a_of_int, len);
  14. end;
  15.  

Other than that, I seem to be missing some type declarations ? For those it is common to prefix them with a letter T (so "tint_a" instead of "int_a")

edit: that gives you a solid
Code: [Select]
./test
Runtime error 201 at $000102B0
  $000102B0  MAX_S_TO_A_OF_INT,  line 10 of test.pas

And that is because your dynamic array has no length while you do store an item in it. You seem to be doing that afterwards in your code.

The compiler gives a warning about that during compilation btw:
Code: [Select]
test.pas(10,22) Warning: function result variable of a managed type does not seem to be initialized

Got it, this is my first time posting, thanks for the reminder !
Title: Re: Help about dynamic array function
Post by: Weeb mindset on August 09, 2020, 08:41:57 am
B.t.w if Val() fails, your code produces wrong results.

Bart

Got it !
Title: Re: Help about dynamic array function
Post by: Weeb mindset on August 09, 2020, 08:49:52 am
Indeed Thaddy.

I simply love it when a compiler is informative that way. It warns you about the error your code is about to make.... if only the compiler could fix that mistake automagically itself somehow .... :)

edit: fwiw variable "u" is used as index to both the string that is parsed as well as the returning dynamic array, which does not make a whole lot of sense imho. And Bart also has a valid point, and in addition what would happen if the provided 'n' inside a string would consist of more than 1 digit.

that's refreshing, thanks !
Title: Re: Help about dynamic array function
Post by: Weeb mindset on August 09, 2020, 09:17:24 am
So after reading the comments, i have made a few changes.

Code: Pascal  [Select][+][-]
  1. function max_s_to_a_of_int(s:string):int_a;
  2. var
  3.     len,u,int,ti1 : integer;
  4.     spec_i        : integer;
  5. begin
  6.      ti1  := 1;
  7.      len := 0;
  8.      for u := 1 to length(s) do
  9.          if s[u] = '_' then inc(len); end;
  10.      setlength(max_s_to_a_of_int,len);    
  11.     for u  := 1 to length(s) do
  12.          if s[u] := '_' then
  13.             begin
  14.                     val(copy(s,ti1,u-1),int,spec_i)  //i don't know other way to cover string to integer, since the input is controlled outside, I'll take it
  15.                     result[u] := int;
  16.                     ti1 := u+1;
  17.             end;
  18. end;
  19.  

I also got a question, how i use it outside ?
The array output is supposed to be inputed into another function
do i use it like a[n], n = integer within low(a)..high(a) inside the function ?
e.g.
Code: Pascal  [Select][+][-]
  1. function a_input(a : array of integer);
  2. begin
  3.         ........
  4. end;
  5.  

while calling it
Code: Pascal  [Select][+][-]
  1. a_input( max_s_to_a_of_int(some_string));
  2.  
Title: Re: Help about dynamic array function
Post by: Bart on August 09, 2020, 11:21:01 am
If after val(copy(s,ti1,u-1),int,spec_i) spec_i is not zero, the conversion failled.
Alternatively you cout use TryStrToInt (which in itself used Val() ).

Bart
Title: Re: Help about dynamic array function
Post by: TRon on August 09, 2020, 12:59:03 pm
Got it, this is my first time posting, thanks for the reminder !
I have no idea what gave it away but I somehow suspected it was your first post ... perhaps it was the postcount ?   :D

But, no worries. That is why I try to put you on the right track so that you know for next time.

I also got a question, how i use it outside ?
You got several options but the basics is the same. Your function returns an array of type int_a.

Code: Pascal  [Select][+][-]
  1. var
  2.   ret: int_a;
  3.  
  4. begin
  5.   // 1. store the value to a "local" one
  6.   ret := max_s_to_a_of_int('1_22_333');
  7.   // and provide that as "input" for the next function
  8.   a_input(ret);
  9.  
  10.   // 2. do it as you showed, directly.
  11.   a_input(max_s_to_a_of_int('1_22_333'));
  12. end.
  13.  
However, do not forget that the "input type" for a_input should also be of type int_a. Pascal uses strong typing.
Title: Re: Help about dynamic array function
Post by: TRon on August 09, 2020, 01:41:21 pm
Oops, I forgot to address a particular question you asked  :-[

do i use it like a[n], n = integer within low(a)..high(a) inside the function ?
Yes, that is perfectly fine to do inside your function. Even stronger, that is the preferred way of doing it.

Besides that you can also use for ... in construct to iterate a dynamic array.

This is my take on your input_a() (I made it a) procedure, since it did not seem to me as if it should return anything.
Code: Pascal  [Select][+][-]
  1. procedure input_a(arr: t_dynamic_long_integer_array);
  2. var
  3.   v: longint;
  4.   i: sizeint;
  5. begin
  6.   // approach 1, using for ... in
  7.   for v in arr
  8.     do writeln('value=',v);
  9.   writeln;
  10.  
  11.   // approach 2, using low(array) to high(array)
  12.   for i:= low(arr) to high(arr)
  13.     do writeln('value=',arr[i]);
  14.   writeln;
  15. end;
  16.  
TinyPortal © 2005-2018