Jump to content
  • 0

How to solve *sd write access violation


Tzuridis

Question


  • Group:  Members
  • Topic Count:  11
  • Topics Per Day:  0.00
  • Content Count:  20
  • Reputation:   0
  • Joined:  06/19/12
  • Last Seen:  

I have this function:

 

BUILDIN_FUNC(guildjoin) {
int guild_id = script_getnum(st,2);
TBL_PC *sd = NULL;
struct guild * g;

----->    sd->guild_invite = guild_id;
    script_pushint( st, guild_reply_invite( sd, guild_id, 1 ) );
    return SCRIPT_CMD_SUCCESS;
}

 

Npc script just invokes:

guildjoin 2

With sd as null or 0 I get sd write access violation. I guess probably for any value.

image.thumb.png.fbe7d7173939f2d0f3b608dc7c1e4b30.png

 

If sd isn't null or not assigned any value, it states calling sd without it being initialized. Both cause the mapserver to crash/restart.
I am not sure how it is not initialized with:
 

TBL_PC *sd;

or
  
TBL_PC* sd

 

sd is the cache the game uses right? My queries to the db are changing the value, is there a different way I can get the game to pull that data and overwrite what is in the cache?

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

  • 1

  • Group:  Members
  • Topic Count:  16
  • Topics Per Day:  0.00
  • Content Count:  660
  • Reputation:   664
  • Joined:  11/12/12
  • Last Seen:  

Heya,

Where to start... "sd" is a variable. What you're attempting to do is similar to...

int x;
int y;

y = x + 5;

It's impossible to assign a value to y if you don't know what the value of x is first. In your code, sd is the variable, but it is never really assigned. It is set to NULL as default (which is good practice), but NULL doesn't mean anything. If you look more closely, the value is actually assigned with "sd = map_charid2sd(script_getnum(st, 3))". It is commented with the "//" in front of it; you need to remove all of those "//" in front of the code.

The "write access violation" comes from you attempting to do sd->guild_invite = guild_id, which in reality corresponds to NULL->guild_invite = guild_id. Obviously NULL doesn't "exist" and you can't assign guild_id to nothing. It's called a violation because you do not have the rights to write to NULL (to keep things simple anyway).

sd isn't a cache, sd is the "map session data". It's what holds the information about your player's current session. You should not be doing queries to your database to update your character (unless your server is offline), that will not work and it's a bad approach. I don't know what you're trying to update though.

Link to comment
Share on other sites

  • 2

  • Group:  Members
  • Topic Count:  3
  • Topics Per Day:  0.00
  • Content Count:  50
  • Reputation:   39
  • Joined:  01/13/12
  • Last Seen:  

58 minutes ago, Tzuridis said:

I have this function:

 


BUILDIN_FUNC(guildjoin) {
int guild_id = script_getnum(st,2);
TBL_PC *sd = NULL;
struct guild * g;

----->    sd->guild_invite = guild_id;
    script_pushint( st, guild_reply_invite( sd, guild_id, 1 ) );
    return SCRIPT_CMD_SUCCESS;
}

 

Npc script just invokes:

guildjoin 2

With sd as null or 0 I get sd write access violation. I guess probably for any value.

image.thumb.png.fbe7d7173939f2d0f3b608dc7c1e4b30.png

 

If sd isn't null or not assigned any value, it states calling sd without it being initialized. Both cause the mapserver to crash/restart.
I am not sure how it is not initialized with:
 


TBL_PC *sd;

or
  
TBL_PC* sd

 

sd is the cache the game uses right? My queries to the db are changing the value, is there a different way I can get the game to pull that data and overwrite what is in the cache?

You're trying to use a pointer variable without initialization, this is why you're receiving this errors/crashes.

Just uncommend the rest of script command and this error is fixed...

Or let the script command like this:

Spoiler

// ADDED BY TED
// guildjoin <guild id>,<char id>;
BUILDIN_FUNC(guildjoin)
{
	int guild_id = script_getnum(st, 2);
	TBL_PC *sd = NULL;
	struct guild *g = NULL;

	// Invalid char id.
	if ((sd = map_charid2sd(script_getnum(st, 3))) == NULL)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_FAILURE;
	}

	// The player is already in one guild.
	if (sd->status.guild)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_SUCCESS;
	}

	// Invalid guild id.
	if ((g = guild_search(guild_id)) == NULL)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_FAILURE;
	}

	// Guild is full.
	if (g->max_member >= MAX_GUILD)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_SUCCESS;
	}

	sd->guild_invite = guild_id;
	sd->guild_invite_account = 0;

	guild_reply_invite(sd, guild_id, 1);
	script_pushint(st, 1);

	return SCRIPT_CMD_SUCCESS;
}

 

And don't forget to change this to be like:

Spoiler

BUILDIN_DEF(guildjoin,"ii"),

 

And the script command will work, don't forget to compile the emulator too.

Link to comment
Share on other sites

  • 1

  • Group:  Content Moderator
  • Topic Count:  55
  • Topics Per Day:  0.02
  • Content Count:  1676
  • Reputation:   703
  • Joined:  12/21/14
  • Last Seen:  

 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  11
  • Topics Per Day:  0.00
  • Content Count:  20
  • Reputation:   0
  • Joined:  06/19/12
  • Last Seen:  

6 hours ago, Cretino said:

You're trying to use a pointer variable without initialization, this is why you're receiving this errors/crashes.

Just uncommend the rest of script command and this error is fixed...

Or let the script command like this:

  Hide contents


// ADDED BY TED
// guildjoin <guild id>,<char id>;
BUILDIN_FUNC(guildjoin)
{
	int guild_id = script_getnum(st, 2);
	TBL_PC *sd = NULL;
	struct guild *g = NULL;

	// Invalid char id.
	if ((sd = map_charid2sd(script_getnum(st, 3))) == NULL)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_FAILURE;
	}

	// The player is already in one guild.
	if (sd->status.guild)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_SUCCESS;
	}

	// Invalid guild id.
	if ((g = guild_search(guild_id)) == NULL)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_FAILURE;
	}

	// Guild is full.
	if (g->max_member >= MAX_GUILD)
	{
		script_pushint(st, 0);

		return SCRIPT_CMD_SUCCESS;
	}

	sd->guild_invite = guild_id;
	sd->guild_invite_account = 0;

	guild_reply_invite(sd, guild_id, 1);
	script_pushint(st, 1);

	return SCRIPT_CMD_SUCCESS;
}

 

And don't forget to change this to be like:

  Hide contents


BUILDIN_DEF(guildjoin,"ii"),

 

And the script command will work, don't forget to compile the emulator too.

Thanks Cretino this solved it. I took out those conditionals because it wouldnt do anything before. I also only had one i because I copied the add party member function and figured it was the same way.

Also Tokei and Sader for the information/clarification

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...