-2

This is a fragment of a class that removes repeated values in fArr.

procedure tArray.removedup; 
var
  K,R : word;
  DArray : array of string;
begin
  SetLength(DArray, max);

  for K := 1 to max do
    if fArr[K] <> '' then
    begin
      fCount := fCount + 1;
      DArray[K - 1] := fArr[K];
    end;//if

  SetLength(DArray, fCount);
  K := 1;
  while K < fCount do
  begin
    for R := K+1 to fCount do
      if DArray[K] = DArray[R] then
      begin
        finalize(DArray[R]);
        if fCount - R > 0 then
          Move(fArr[R + 1], DArray[R], SizeOf(string) * (fCount - R));
        Initialize(DArray[fCount - 1]);
        SetLength(DArray, fCount);
      end; //if

    K := K + 1;
  end;//while

  for K := 1 to fCount do
    fArr[K] := DArray[K-1];
end;

I know it looks messy... but the problem is actually at the last for loop. The program bombs out saying "Invalid pointer operation"

mg30rg
  • 1,311
  • 13
  • 24
Shilon
  • 19
  • 4
  • The Answer to this http://stackoverflow.com/questions/14397182/einvalidpointer-message-with-invalid-pointer-operation might give you a hint – BigM Sep 30 '14 at 13:27
  • 1
    Are you sure you wish your loops to go to `fCount`? Your code is barely usable and I can't really know the value of lots of practically global variables like `max`, but a loop like `for intx := 0 to count do` is at least suspicious. Normally Delphi arrays are 0 based so a loop parsing the entire array looks like `for intx := 0 to count - 1 do`. – mg30rg Sep 30 '14 at 13:28
  • Please format the code so that it is legible – David Heffernan Sep 30 '14 at 13:48
  • 2
    Turn on range checking, and then never turn it off. Ever. Step through your code with the debugger and find the problem. If you can't do that, then get a pencil and paper, and work through your code by hand. Pick a small number of elements for your array; say, 5. Draw the array on your paper and update it as you work your way through the code. – Rob Kennedy Sep 30 '14 at 13:50

1 Answers1

1

There are many things wrong with your code. It's difficult to know where to start. There is excessive copying. Much confusion over zero-based array indices. And worst of all, that call to Move that goes behind the compiler's back and copies managed objects without the compiler getting a chance to reference count properly.

Any of these problems could be responsible for your runtime error. I won't attempt to debug or fix your code. I don't think anything useful can be salvaged from it. Here's a function that removes duplicates:

function Deduped(const input: array of string): TStringArray;
var
  i, j, Count: Integer;
  Found: Boolean;
begin
  Count := 0;
  SetLength(Result, Length(input));
  for i := 0 to high(input) do begin
    if input[i] <> '' then begin
      Found := False;
      for j := 0 to Count-1 do begin
        if input[i] = Result[j] then begin
          Found := True;
          break;
        end;
        if not Found then begin
          Result[Count] := input[i];
          inc(Count);
        end;
      end;
    end;
  end;
  SetLength(Result, Count);
end;

I'm ignoring empty strings as I think your code attempts to do.

The function is simple enough. It allocates an array large enough to hold all the values. Then it works through the input values and for each one checks if it has already been stored in the output array. If not then it adds the value to the array. Finally the output array is resized to the final length. That is the number of unique non-empty strings that were found.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Nice code - but that is no surprise. I'm more curious about the why. I mean... more than likely that the op will only copy-paste your code into her(/his) codebase without learning anything. Wouldn't it be more productive to "lead" @Shilon to find out the solution by her(/him)self? – mg30rg Oct 01 '14 at 07:34
  • @mg30rg: Perhaps, yes, but his code is so convoluted that it would be an incredible piece of work just to go through each line and explain what is wrong there. Sometimes, showing how something is done is better than telling how it should not be done. – Rudy Velthuis Oct 01 '14 at 07:49
  • @RudyVelthuis I doubt that leading would work here. It takes a lot of experience to be able to write clean code. I suspect any attempt to lead would result in confusion and epic comment trails. If the asker studies this closely then they will be able to absorb a number of useful idioms. – David Heffernan Oct 01 '14 at 08:00
  • @RudyVelthuis - Again, I'm not really sure that I'm right. It is just an **opinion**, but I think people who write code like that are not coming here to _learn_. They came here to get their code fixed or rewritten and they only learn if the SO community forces them to. – mg30rg Oct 01 '14 at 08:00
  • 1
    @mg30rg Maybe. Maybe not. Sometimes people just want the code fixed and don't want to learn. Nothing can be done with them. No amount of forcing will persuade them to learn. But perhaps this asker does want to learn. The reason I write answers here is to help people that want to learn. I enjoy doing that. – David Heffernan Oct 01 '14 at 08:03
  • @DavidHeffernan - Which is nice of you, and I admire it. _:nosarcasmintended:_ – mg30rg Oct 01 '14 at 08:31