Forum > Windows

Access Violation on Procedure Exit

<< < (4/4)

Thaddy:
On Windows CE Pchar <> PAnsiChar but PUnicodeChar/PWideChar. Change all PChar declarations to explicit PAnsiChar and all Chars to explicit AnsiChar.
Last time I programmed for CE is a long time ago, so plz consider that an oversight.
CE is a unicode system since at least CE v6, which means that the string types are interpreted accordingly.

Remy Lebeau:

--- Quote from: therealhades on May 29, 2024, 01:01:03 pm ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---ReadStringVar(btn[0]); // working, got Messagebox (last line of procedure (Line 202))ShowMessage('test'); // not working, got AV
--- End quote ---

That implies you are corrupting memory or the call stack.


--- Quote from: therealhades on May 29, 2024, 01:01:03 pm ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TfrmMain.PlcStringToString(APlcString: array of char): string;var  i: integer;begin  Result:= '';  for i:= 0 to length(APlcString) do begin    if APlcString[i] <> Chr($00) then      Result:= Result + APlcString[i]    else exit;  end;end;
--- End quote ---

This is a buffer overflow waiting to happen if APlcString is not null-terminated.  An open array is 0-indexed, so your loop needs to use length(APlcString)-1 (or High(APlcString)) instead, otherwise you go out of bounds.

Rather than doing a concatenation on every loop iteration, I would suggest using SetString() instead, eg:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TfrmMain.PlcStringToString(APlcString: array of char): string;var  len: integer;begin  for len := 0 to Length(APlcString)-1 do begin    if APlcString[len] = Chr($00) then Break;  end;  SetString(Result, PChar(APlcString), len);end;
Alternatively:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TfrmMain.PlcStringToString(APlcString: array of char): string;begin  SetString(Result, PChar(APlcString), Length(APlcString));  Result := TrimRight(Result);end;

--- Quote from: therealhades on May 29, 2024, 01:01:03 pm ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmMain.ReadStringVar(var aVar: TStringVar);var  tmp: array of char;  ads: longint;begin  if aVar.Handle = 0 then    ads:= AdsSyncReadWriteReq(@AMS, ADSIGRP_SYM_HNDBYNAME, $0000, sizeof(aVar.Handle), @aVar.Handle, Length(aVar.VarName) + 1, @aVar.VarName[1])  else ads:= 0;  SetLength(tmp, 255);  if ads = 0 then    ads:= AdsSyncReadReq(@AMS, ADSIGRP_SYM_VALBYHND, aVar.Handle, Length(tmp), @tmp[0]);  if ads = 0 then aVar.Data:= PlcStringToString(tmp);  ShowMessage('in Procedure: ' + aVar.Data);end;
--- End quote ---

There is no need to allocate tmp dynamically.

More importantly, a ShortString is not null-terminated, but you are passing in a pointer directly to its characters, and passing in +1 for its length as if a null terminator were present. You need to pass in a valid null-terminated string, eg:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmMain.ReadStringVar(var aVar: TStringVar);var  sVarName: AnsiString;  tmp: array[0..255] of AnsiChar;  ads: longint;begin  if aVar.Handle = 0 then begin    sVarName := aVar.VarName;    ads := AdsSyncReadWriteReq(@AMS, ADSIGRP_SYM_HNDBYNAME, $0000, sizeof(aVar.Handle), @aVar.Handle, Length(sVarName) + 1, PChar(sVarName));  end else    ads := 0;  if ads = 0 then begin    ads := AdsSyncReadReq(@AMS, ADSIGRP_SYM_VALBYHND, aVar.Handle, Length(tmp), @tmp[0]);    if ads = 0 then aVar.Data := PlcStringToString(tmp);  end;  ShowMessage('in Procedure: ' + aVar.Data);end;
In which case, consider changing TStringVar back to using (Ansi)String instead of String[255] for its VarName field:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TStringVar = record    VarName: AnsiString;    ...end;... ads := AdsSyncReadWriteReq(..., Length(aVar.VarName) + 1, PAnsiChar(aVar.VarName));

Navigation

[0] Message Index

[*] Previous page

Go to full version