wcstombs 分段错误

发布于 2024-08-21 10:42:25 字数 514 浏览 4 评论 0原文

奇怪的是,这段代码编译时没有警告:

int
main (void)
{
  int i;  
  char pmbbuf[4]; 

  wchar_t *pwchello = L"1234567890123456789012345678901234567890";

  i = wcstombs (pmbbuf, pwchello, wcslen(pwchello)* MB_CUR_MAX + 1);

  printf("%d\n", MB_CUR_MAX);
  printf ("   Characters converted: %u\n", i);
  printf ("   Multibyte character: %s\n\n", pmbbuf);

  return 0;
}

但是当我运行 ./a.out 时,它打印了:

1
转换字符数:40
多字节字符:1234(

分段错误

关于分段错误的原因有什么想法吗?

The strange thing is that this code compiles with no warnings:

int
main (void)
{
  int i;  
  char pmbbuf[4]; 

  wchar_t *pwchello = L"1234567890123456789012345678901234567890";

  i = wcstombs (pmbbuf, pwchello, wcslen(pwchello)* MB_CUR_MAX + 1);

  printf("%d\n", MB_CUR_MAX);
  printf ("   Characters converted: %u\n", i);
  printf ("   Multibyte character: %s\n\n", pmbbuf);

  return 0;
}

But when I run ./a.out it printed:

1
Characters converted: 40
Multibyte character: 1234(

Segmentation fault

Any ideas about what causes the segmentation fault?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花伊自在美 2024-08-28 10:42:25

您会遇到缓冲区溢出,因为您在转换后没有以 null 终止缓冲区,并且缓冲区大小也不足以保存结果。

您可以动态分配内存,因为您事先不知道需要多少内存:

int i;
char pmbbuf*;
wchar_t *pwchello = L"1234567890123456789012345678901234567890";
// this will not write anything, but return the number of bytes in the result
i = wcstombs (0, pwchello, wcslen(pwchello)* MB_CUR_MAX + 1);
//allocate memory - +1 byte for the trailing null, checking for null pointer returned omitted (though needed)
pmbbuf = malloc( i + 1 );
i = wcstombs (pmbbuf, pwchello, wcslen(pwchello)* MB_CUR_MAX + 1);
//put the trailing null
pmbbuf[i] = 0;
//whatever you want to do with the string - print, e-mail, fax, etc.
// don't forget to free memory
free( pmbbuf );
//defensive - to avoid misuse of the pointer 
pmbbuf = 0;

You encounter buffer overrun because you don't null-terminate the buffer after conversion and the buffer size is also not enough to hold the result.

You could allocate memory dynamically since you don't know in advance how much memory is required:

int i;
char pmbbuf*;
wchar_t *pwchello = L"1234567890123456789012345678901234567890";
// this will not write anything, but return the number of bytes in the result
i = wcstombs (0, pwchello, wcslen(pwchello)* MB_CUR_MAX + 1);
//allocate memory - +1 byte for the trailing null, checking for null pointer returned omitted (though needed)
pmbbuf = malloc( i + 1 );
i = wcstombs (pmbbuf, pwchello, wcslen(pwchello)* MB_CUR_MAX + 1);
//put the trailing null
pmbbuf[i] = 0;
//whatever you want to do with the string - print, e-mail, fax, etc.
// don't forget to free memory
free( pmbbuf );
//defensive - to avoid misuse of the pointer 
pmbbuf = 0;
安穩 2024-08-28 10:42:25

您正在尝试将一个肯定超过 4 个字符的字符串放入可容纳 4 个字符的字符数组中。由于您没有指定“4”作为最大大小,因此转换将写入它不拥有的内存或可能被其他变量使用的内存、堆栈上函数返回值等内部数据或类似数据。当您覆盖在调用 wcstombs 之前推送到堆栈上的数据(堆栈自上而下增长)时,这将导致段错误。

You're trying to put a string that's definitely longer than 4 chars into a char array that can hold 4 characters. As you don't specify '4' as the maximum size, the conversion will write into memory that it doesn't own or that might be used by other variables, house keeping data like function return values on the stack or similar. This will lead to the seg fault as you're overwriting data that was pushed on the stack (stacks grow top-down) before you called wcstombs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文