0

I am currently developing a program with WinHTTP and I'm getting stuck while modifying the value of an LPWSTR in the URL_COMPONENT struct.

I make a simple script that describes my problem:

#include <windows.h>
#include <stdio.h>
 
int main(int argc, char const *argv[])
{
  LPWSTR country = L"America, England, Belgium";
  size_t pos = 0;
  while(country[pos] != 44) pos++;
  country[pos] = 0;
  printf("%ls\n", country); // 0x4015b0
  return 0;
}

The program receives a SIGSEGV signal on the line country[pos] = 0

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • You can't modify string literals. You need to copy it to a buffer to be able to modify it. – Jonathan Potter Jul 26 '23 at 11:13
  • Well yeah, but this will add more variable. Are you have another alternative? – Orang Keren Jul 26 '23 at 11:45
  • 2
    @OrangKeren A string literal is read-only data. You have no choice but to make a copy of the data if you want to modify it. But in this particular case, you don't need to modify it. You can instead tell `printf` how many characters to print, eg: `printf("%.*ls\n", pos, country) ` – Remy Lebeau Jul 26 '23 at 14:37

1 Answers1

3
LPWSTR country = L"America, England, Belgium";

country is a pointer to the string literal. Attempt to modify string literal invokes Undefined Behaviour which in your case expresses itself as SEGFAULT.

You need to define modifiable wchar array:

wchar_t country[] = L"America, England, Belgium";

You can also use compound literal to initialize pointer:

LPWSTR country = (wchar_t[]){L"America, England, Belgium"};
0___________
  • 60,014
  • 4
  • 34
  • 74
  • Magic! wchar_t is compatible pointer type however its name far from LPWSTR... – Orang Keren Jul 26 '23 at 11:54
  • @OrangKeren beauty of stupid MS typedefs https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/50e9ef83-d6fd-4e22-a34a-2c6b4e3c24f3 – 0___________ Jul 26 '23 at 11:58
  • @OrangKeren If you're going to be coding on windows then [This documentation](https://learn.microsoft.com/en-us/windows/win32/learnwin32/windows-coding-conventions) may be useful as it explains the what and why of the `typedef`s. Not all of them but it's a good place to start understanding it. – Mgetz Jul 26 '23 at 12:03
  • `WCHAR` would be the macro if you want stay in that system. – ikegami Jul 26 '23 at 18:06
  • *"stupid MS typedefs"* is what establishes a stable ABI. If you can find me a competing solution that doesn't require this indirection, I'll make sure to forward it to Microsoft for consideration. As for the pattern used: ABI types are spelled in `ALL_UPPERCASE`. They aren't meant to be used in your C or C++ code unless you're specifying an interface with a strict ABI. – IInspectable Aug 06 '23 at 13:23
  • @IInspectable hiding pointers behind typedefs etc etc. It is crap. Naming convention is not the issue. It is simply bad – 0___________ Aug 06 '23 at 13:27
  • This is neither about "hiding", nor about "naming conventions". It is about establishing a stable ABI. Across several decades. Can you show me a competing solution that doesn't involve indirections, and has a proven track record spanning several decades? If all you have to offer is *"It is simply bad"* then, in all likelihood, you haven't understood the problem a stable ABI solves. – IInspectable Aug 06 '23 at 14:02
  • @IInspectable you simply do understand why it is bad. EOD. – 0___________ Aug 06 '23 at 17:15
  • I do understand that you might be confused. I do not understand what's bad about a stable ABI. I do understand that you haven't got an alternative solution that's better. Might want to consider removing those comments that make you look like haven't got so much as a clue. – IInspectable Aug 06 '23 at 19:05