Thread overview
Access violation using append/concatenate operator "~"
Mar 26, 2005
V
Mar 26, 2005
Derek Parnell
Mar 26, 2005
V
Mar 26, 2005
John C
Mar 27, 2005
V
Mar 26, 2005
Derek Parnell
Mar 27, 2005
V
March 26, 2005
I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:

<code>

void printFunc(char[] msg)
{
	msg ~= "\n";	// Error
	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
}

</code>

Am I doing something wrong here?  Thanks :)
March 26, 2005
On Fri, 25 Mar 2005 19:51:13 -0800, V wrote:

> I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:
> 
> <code>
> 
> void printFunc(char[] msg)
> {
> 	msg ~= "\n";	// Error
> 	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
> }
> 
> </code>
> 
> Am I doing something wrong here?  Thanks :)

By any chance is the data being passed a string literal *and* you are running on a linux system? That would cause one. If so, try recoding it as ...

 void printFunc(char[] msg)
 {
 	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) (msg~"\n").ptr );
 }

-- 
Derek Parnell
Melbourne, Australia
26/03/2005 4:34:31 PM
March 26, 2005
Derek Parnell wrote:
> On Fri, 25 Mar 2005 19:51:13 -0800, V wrote:
> 
> 
>>I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:
>>
>><code>
>>
>>void printFunc(char[] msg)
>>{
>>	msg ~= "\n";	// Error
>>	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
>>}
>>
>></code>
>>
>>Am I doing something wrong here?  Thanks :)
> 
> 
> By any chance is the data being passed a string literal *and* you are
> running on a linux system? That would cause one. If so, try recoding it as
> ...
> 
>  void printFunc(char[] msg)
>  {
>  	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) (msg~"\n").ptr );
>  }
> 

I'm using windows xp and here is the code that precedes the function call:

<code>

char[] text;
GETTEXTEX gtx;
gtx.cb = 151;
gtx.flags = GT_DEFAULT;
gtx.lpDefaultChar = null;
gtx.codepage = CP_ACP;
gtx.lpUsedDefChar = null;
SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text );
printFunc(text);

</code>

The output is fine if I don't use the append operator but will not start on a new line.
March 26, 2005
"V" <v@pathlink.com> wrote in message news:d23c7p$26o9$1@digitaldaemon.com...
> Derek Parnell wrote:
>> On Fri, 25 Mar 2005 19:51:13 -0800, V wrote:
>>
>>
>>>I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:
>>>
>>><code>
>>>
>>>void printFunc(char[] msg)
>>>{
>>> msg ~= "\n"; // Error
>>> SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
>>>}
>>>
>>></code>
>>>
>>>Am I doing something wrong here?  Thanks :)
>>
>>
>> By any chance is the data being passed a string literal *and* you are
>> running on a linux system? That would cause one. If so, try recoding it
>> as
>> ...
>>
>>  void printFunc(char[] msg)
>>  {
>>  SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM)
>> (msg~"\n").ptr );
>>  }
>>
>
> I'm using windows xp and here is the code that precedes the function call:
>
> <code>
>
> char[] text;
> GETTEXTEX gtx;
> gtx.cb = 151;
> gtx.flags = GT_DEFAULT;
> gtx.lpDefaultChar = null;
> gtx.codepage = CP_ACP;
> gtx.lpUsedDefChar = null;
> SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx,
> cast(LPARAM)&text );

You're passing the address of a char[], not a pointer to a null-terminated string. Try this:

    char[] text = new char[151];
    ...
    gtx.cb = text.length;
    ...
    SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx,
cast(LPARAM)std.string.toStringz(text));

> printFunc(text);
>
> </code>
>
> The output is fine if I don't use the append operator but will not start on a new line.


March 26, 2005
On Sat, 26 Mar 2005 01:55:44 -0800, V wrote:

> Derek Parnell wrote:
>> On Fri, 25 Mar 2005 19:51:13 -0800, V wrote:
>> 
>> 
>>>I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:
>>>
>>><code>
>>>
>>>void printFunc(char[] msg)
>>>{
>>>	msg ~= "\n";	// Error
>>>	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
>>>}
>>>
>>></code>
>>>
>>>Am I doing something wrong here?  Thanks :)
>> 
>> 
>> By any chance is the data being passed a string literal *and* you are running on a linux system? That would cause one. If so, try recoding it as ...
>> 
>>  void printFunc(char[] msg)
>>  {
>>  	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) (msg~"\n").ptr );
>>  }
>> 
> 
> I'm using windows xp and here is the code that precedes the function call:
> 
> <code>
> 
> char[] text;
> GETTEXTEX gtx;
> gtx.cb = 151;
> gtx.flags = GT_DEFAULT;
> gtx.lpDefaultChar = null;
> gtx.codepage = CP_ACP;
> gtx.lpUsedDefChar = null;
> SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text );
> printFunc(text);
> 
> </code>
> 
> The output is fine if I don't use the append operator but will not start on a new line.

The first thing I notice is that you set the cb field to 151, meaning that the buffer size is 150 bytes + 1 for the null char. However, you haven't allocated anything in the buffer.

I think you need "text.length = gtx.cb;" just before sending the EM_GETTEXTEX message.

Then I think the send message call should more like ...

SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text[0]
);

In other words, pass the address of the first byte in the buffer. Unlike, C/C++, when if you declare an array such as char[] text, then use '&text', you are passing the address of the 8-byte dynamic array descriptor rather than the address of the first byte in the array. This means that the SendMessage routine will write over those 8 bytes, and possibly more, thus messing up your RAM. Access violations are almost guaranteed at some stage.


-- 
Derek Parnell
Melbourne, Australia
http://www.dsource.org/projects/build
26/03/2005 10:27:00 PM
March 27, 2005
John C wrote:
> "V" <v@pathlink.com> wrote in message news:d23c7p$26o9$1@digitaldaemon.com...
> 
>>Derek Parnell wrote:
>>
>>>On Fri, 25 Mar 2005 19:51:13 -0800, V wrote:
>>>
>>>
>>>
>>>>I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:
>>>>
>>>><code>
>>>>
>>>>void printFunc(char[] msg)
>>>>{
>>>>msg ~= "\n"; // Error
>>>>SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
>>>>}
>>>>
>>>></code>
>>>>
>>>>Am I doing something wrong here?  Thanks :)
>>>
>>>
>>>By any chance is the data being passed a string literal *and* you are
>>>running on a linux system? That would cause one. If so, try recoding it as
>>>...
>>>
>>> void printFunc(char[] msg)
>>> {
>>> SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) 
>>>(msg~"\n").ptr );
>>> }
>>>
>>
>>I'm using windows xp and here is the code that precedes the function call:
>>
>><code>
>>
>>char[] text;
>>GETTEXTEX gtx;
>>gtx.cb = 151;
>>gtx.flags = GT_DEFAULT;
>>gtx.lpDefaultChar = null;
>>gtx.codepage = CP_ACP;
>>gtx.lpUsedDefChar = null;
>>SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text );
> 
> 
> You're passing the address of a char[], not a pointer to a null-terminated string. Try this:
> 
>     char[] text = new char[151];
>     ...
>     gtx.cb = text.length;
>     ...
>     SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)std.string.toStringz(text));
> 
> 
>>printFunc(text);
>>
>></code>
>>
>>The output is fine if I don't use the append operator but will not start on a new line. 
> 
> 
> 


Using std.string.toStringsz(text) produces garbage when I display it in the console window.
March 27, 2005
Derek Parnell wrote:
> On Sat, 26 Mar 2005 01:55:44 -0800, V wrote:
> 
> 
>>Derek Parnell wrote:
>>
>>>On Fri, 25 Mar 2005 19:51:13 -0800, V wrote:
>>>
>>>
>>>
>>>>I have a function that passes a string to be displayed on a screen and when using the "~" operator, causes an access violation:
>>>>
>>>><code>
>>>>
>>>>void printFunc(char[] msg)
>>>>{
>>>>	msg ~= "\n";	// Error
>>>>	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) &msg);
>>>>}
>>>>
>>>></code>
>>>>
>>>>Am I doing something wrong here?  Thanks :)
>>>
>>>
>>>By any chance is the data being passed a string literal *and* you are
>>>running on a linux system? That would cause one. If so, try recoding it as
>>>...
>>>
>>> void printFunc(char[] msg)
>>> {
>>> 	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) (msg~"\n").ptr );
>>> }
>>>
>>
>>I'm using windows xp and here is the code that precedes the function call:
>>
>><code>
>>
>>char[] text;
>>GETTEXTEX gtx;
>>gtx.cb = 151;
>>gtx.flags = GT_DEFAULT;
>>gtx.lpDefaultChar = null;
>>gtx.codepage = CP_ACP;
>>gtx.lpUsedDefChar = null;
>>SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text );
>>printFunc(text);
>>
>></code>
>>
>>The output is fine if I don't use the append operator but will not start on a new line.
> 
> 
> The first thing I notice is that you set the cb field to 151, meaning that
> the buffer size is 150 bytes + 1 for the null char. However, you haven't
> allocated anything in the buffer.
> 
> I think you need "text.length = gtx.cb;" just before sending the
> EM_GETTEXTEX message.
> 
> Then I think the send message call should more like ...
> 
> SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text[0]
> );
> 
> In other words, pass the address of the first byte in the buffer. Unlike,
> C/C++, when if you declare an array such as char[] text, then use '&text',
> you are passing the address of the 8-byte dynamic array descriptor rather
> than the address of the first byte in the array. This means that the
> SendMessage routine will write over those 8 bytes, and possibly more, thus
> messing up your RAM. Access violations are almost guaranteed at some stage.
> 
> 


Using &text[0] in SendMessageA(wndInput...  works but now the append operation is not displayed, meaning the newline is not added, but it doesn't throw an exception.  Maybe there is a null terminator at the end which is why the newline is not displayed?

<code>

SendMessageA(wndInput, EM_GETTEXTEX, cast(WPARAM)&gtx, cast(LPARAM)&text[0]);
text ~= "\n";
printFunc(text);


void printFunc(char[] msg)
{
	SendMessageA(wndConsole, EM_REPLACESEL, 0, cast(LPARAM) 			&msg[0]);
}

</code>
March 27, 2005
Derek Parnell wrote:

> By any chance is the data being passed a string literal *and* you are
> running on a linux system? That would cause one. 

That is not true. Concatenation to an array creates a new one...

Setting the current array contents by indexing would, however ?

--anders