[SOLVED] Synapse Twitter application: access violation? lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- BigChimp · 2012-06-14 14:50 Hi all, I've been working on my Twitter/oauth library and get it to retrieve tweets and display them. Not being much of a JSON guru, I took the copy/paste approach... which seems to work. However, running with debugging turned on gives an access violation at the end of the program.(as well as a memory leak)... probably something stupid wrt my JSON parsing - I'm not entirely clear on what objects I should free and when... Here's a snippet to whet your appetite: Code: [Select]  Twitter:=OAuth1.Create;   try     // todo: use fcl-json or xml to parse these results...     try       Twitter.GetPINFunction:=@GetPIN; //Register PIN callback with object       Twitter.ConsumerKey:=ConsumerKey;       Twitter.ConsumerSecret:=ConsumerSecret;       // Next two will be empty if not preauthorized and using PIN auth       Twitter.AuthToken:=AccessToken;       Twitter.AuthSecret:=AccessTokenSecret;       Twitter.CallBackURL:='oob';       Twitter.Protocol:='1.1';       //Deprecated:       //http://twitter.com/statuses/public_timeline.json       Success:=Twitter.OAuthHTTPMethod('GET', 'https://api.twitter.com/1/statuses/home_timeline.json');       // Returns json array with objects that represent tweets. A tweet object's user is itself an object     except       on E: Exception do       begin         writeln('Exception: '+E.ClassName+'/'+E.Message);         Success:=false;       end;     end;     if Success then     begin       write('Welcome');       if Twitter.ScreenName<>'' then         writeln(', '+Twitter.ScreenName)       else         if Twitter.UserID<>'' then writeln(', user '+Twitter.UserID) else writeln('');       if (AccessToken='') and (AccessTokenSecret='') then       begin         //AccessToken:=Twitter.AuthToken;         //AccessTokenSecret:=Twitter.AuthSecret;         writeln('Your appliction is authenticated; you can try to use these codes next time:');         writeln('Access token:');         writeln(Twitter.AuthToken);         writeln('Access secret:');         writeln(Twitter.AuthSecret);       end;       ReturnBody:=TStringList.Create;       try         ReturnBody.LoadFromStream(Twitter.Document);         writeln('Tweets:');         Parser:=TJSONParser.Create(Returnbody.Text);       finally         ReturnBody.Free;       end;       try         Tweets:=Parser.Parse;         if not(Assigned(Tweets)) then         begin           writeln('No tweets found or other failure.');         end         else         begin           for TweetCounter:=0 to Tweets.Count-1 do           begin             Tweet:=TJSONObject(Tweets.Items[TweetCounter]);             //created_at (date): in this format Thu Jun 14 11:21:51 +0000 2012             //id (integer/long int?             //text             //then user is an array of is, name, screen_name etc             writeln(DateTimeToStr(ParseTwitterTimestamp(Tweet.Strings[ 'created_at']))+               #9+Tweet.Strings['text']);           end;         end;       finally         FreeAndNil(Parser);       end;     end     else     begin       // No success       writeln('Could not get status.');       writeln('Result code: '+inttostr(Twitter.ResultCode));     end;   finally     Twitter.Free;   end; Full source code at https://bitbucket.org/reiniero/fpctwit/downloads Lazarus 1.1 (SVN 37399), FPC 2.6.1 x86, Windows, dwarf with sets debugging+heaptrc Anybody knows what I'm doing wrong? Thanks. ---------------------------------------------------------------------- ludob · 2012-06-14 14:58 Quotedwarf with sets debugging+heaptrcUse stabs: http://bugs.freepascal.org/view.php?id=20296 ---------------------------------------------------------------------- BigChimp · 2012-06-14 15:12 Ok, that doesn't give an AV anymore, just a number of leaks (a lot of them on the last line below: Code: [Select]var   Application: Tfpctwit; begin   Application:=Tfpctwit.Create(nil);   Application.Run;   Application.Free;    So does this mean that there is a mem leak outside my program, somewhere in the LCL or RTL/FCL? Tried to free the Tweet and Tweets JSON object/data but got an AV again - they're probably deleted when the parser object that created them is freed. ---------------------------------------------------------------------- ludob · 2012-06-14 15:53 Code: [Select]      finally         Tweets.Free;         FreeAndNil(Parser);       end; works for me. ---------------------------------------------------------------------- BigChimp · 2012-06-14 16:05 Thanks, does for me too. Still get confused when to free objects - whenever you create them yourself... or when you have a procedure create them for you... It probably went wrong when I tried to free Tweet, which just was: Code: [Select]Tweet:=TJSONObject(Tweets.Items[TweetCounter]); ... in other words a reference to an existing object. IIUC, once the Tweets object goes out of scope/is freed, Tweet gets invalidated, so freeing it yourself will cause a problem as it you're trying to free something that's already been freed. Or something. Seems like my .Net past is coming back to haunt me now and again... there we created objects with gay abandon and let the garbage collection sort it out ---------------------------------------------------------------------- ludob · 2012-06-14 16:28 Don't know why TJSONParser was written that way but Parse is a function that returns an object. If the result of the parsing was accessible as a property TJSONParser could have destroyed it automatically. Because it is a function, it hands over the object to the caller and it is up to the caller to destroy it. It is a subtlety that is error prone. Freeing a Tweets.Items[] directly leaves still the entry in Tweets that now points to nil. To remove an item do something like TJSONObject(Tweets).Delete(TweetCounter);