å°ãåã«ãã³ã³ãã¥ãŒã¿ãŒãµã€ãšã³ã¹ã«ã¬ããžã®æåž«ã®1人ãé¢äžãããããªãèå³æ·±ãäºä»¶ãç§ã«èµ·ãããŸããã
Linuxããã°ã©ãã³ã°ã«ã€ããŠã®äŒè©±ã¯ããã®äººãã·ã¹ãã ããã°ã©ãã³ã°ã®è€éãã¯å®éã«ã¯éåžžã«èªåŒµãããŠãããšäž»åŒµãå§ãããšããäºå®ã«åŸã ã«å€ãããŸããã Cèšèªã¯ãå®éã«ã¯Linuxã«ãŒãã«ã®ããã«ïŒåœŒã®èšèã§ïŒäžèŽããããã«åçŽã§ãã
ç§ã¯LinuxãæèŒããã©ããããããæã£ãŠããŠãããã«ã¯CèšèªïŒgccãvimãmakeãvalgrindãgdbïŒã§éçºããããã®çŽ³å£«çšã®ãŠãŒãã£ãªãã£ã»ããããããŸããã ãã®ãšãã©ã®ãããªç®æšãèšå®ãããèŠããŠããŸããããæ°ååŸã察æŠçžæã¯ãã®ã©ãããããã®åŸãã«ããŠãåé¡ãå®å šã«è§£æ±ºããæºåãã§ããŠããŸããã
ãããŠãæåéãæåã®è¡ã§ãã¡ã¢ãªã...è¡ã®äžã«å²ãåœãŠããšãã«ã圌ã¯é倧ãªééããç¯ããŸããã
char *str = (char *)malloc(sizeof(char) * strlen(buffer));
ãããã¡-ããŒããŒãããã®ããŒã¿ãå ¥åãããã¹ã¿ãã¯å€æ°ã
ãããã«äœãåé¡ã¯ãããŸããïŒããšå°ãã人ãå¿ ããããšæããŸãã
å€åç§ãä¿¡ããŠã
ãããŠäœãæ£ç¢ºã«-ã«ããã§èªãã§ãã ããã
ã¡ãã£ãšããçè«-äžçš®ã®FaceWithoutã
ããã£ãŠããå Žåã¯ã次ã®ããããŒãŸã§ã¹ã¯ããŒã«ããŸãã
Cã®æååã¯æåã®é åã§ãããåžžã«é©å㪠'\ 0'-è¡æ«æåã§çµããå¿ èŠããããŸãã ã¹ã¿ãã¯äžã®è¡ïŒéçïŒã¯ã次ã®ããã«å®£èšãããŸãã
char str[n] = { 0 };
nã¯æåé åã®ãµã€ãºã§ãæååã®é·ããšåãã§ãã
å²ãåœãŠ{0}-è¡ã®ããŒãåãïŒãªãã·ã§ã³ããããªãã§å®£èšã§ããŸãïŒã çµæã¯ãmemsetïŒstrã0ãsizeofïŒstrïŒïŒããã³bzeroïŒstrãsizeofïŒstrïŒïŒé¢æ°ã®å®è¡ãšåãã§ãã ã¬ããŒãžãåæåãããŠããªãå€æ°ã«ååšããã®ãé²ãããã«äœ¿çšãããŸãã
ã¹ã¿ãã¯äžã§ããããã«è¡ãåæåã§ããŸãã
char buf[BUFSIZE] = "default buffer text\n";
ãŸããæååããã€ã³ã¿ãŒãšããŠå®£èšããããŒãïŒããŒãïŒã«ã¡ã¢ãªãå²ãåœãŠãããšãã§ããŸãã
char *str = malloc(size);
size-æååã«å²ãåœãŠããã€ãæ°ã ãã®ãããªè¡ã¯åçãšåŒã°ããŸãïŒç®çã®ãµã€ãºãåçã«èšç®ããããããå²ãåœãŠãããã¡ã¢ãªãµã€ãºã¯reallocïŒïŒé¢æ°ã䜿çšããŠãã€ã§ãå¢ããããšãã§ããŸãïŒã
ã¹ã¿ãã¯å€æ°ã®å Žåãè¡šèšæ³nã䜿çšããŠé åã®ãµã€ãºã決å®ããããŒãäžã®å€æ°ã®å Žåãè¡šèšæ³ãµã€ãºã䜿çšããŸããã ãããŠãããã¯ãã¹ã¿ãã¯äžã®ã¢ããŠã³ã¹ã¡ã³ããšããŒãäžã®ã¡ã¢ãªå²ãåœãŠã䌎ãã¢ããŠã³ã¹ã¡ã³ãã®éãã®çã®æ¬è³ªãå®å šã«åæ ããŠããŸããããã¯ãèŠçŽ æ°ã«ã€ããŠè©±ããšãã«éåžžnã䜿çšãããããã§ãã ãããŠããµã€ãºã¯ãŸã£ããå¥ã®è©±ã§ã...
ç§ã¯æãã ä»ã®ãšããååã§ãã ã©ãã
Valgrindã¯ç§ãã¡ãå©ããŸã
åã®èšäºã§ã圌ã«ã€ããŠãèšåããŸããã Valgrind ïŒ æé -wiki èšäº ã 2-å°ããªããŠã㌠ïŒã¯ãããã°ã©ããã¡ã¢ãªãªãŒã¯ãšã³ã³ããã¹ããšã©ãŒã远跡ããã®ã«åœ¹ç«ã€éåžžã«äŸ¿å©ãªããã°ã©ã ã§ãããããã¯ãæååãæäœãããšãã«æãé »ç¹ã«è¡šç€ºããããã®ã§ãã
ç§ãèšåããããã°ã©ã ã«äŒŒããã®ãå®è£ ããå°ããªãªã¹ããèŠãŠãvalgrindã§å®è¡ããŠã¿ãŸãããã
#include <stdio.h> #include <stdlib.h> #include <string.h> #define HELLO_STRING "Hello, Habr!\n" void main() { char *str = malloc(sizeof(char) * strlen(HELLO_STRING)); strcpy(str, HELLO_STRING); printf("->\t%s", str); free(str); }
ãããŠãå®éã«ã¯ãããã°ã©ã ã®çµæïŒ
[indever@localhost public]$ gcc main.c [indever@localhost public]$ ./a.out -> Hello, Habr!
ãããŸã§ã®ãšãããç°åžžãªããšã¯äœããããŸããã ã§ã¯ãvalgrindã䜿çšããŠãã®ããã°ã©ã ãå®è¡ããŸãããã
[indever@localhost public]$ valgrind --tool=memcheck ./a.out ==3892== Memcheck, a memory error detector ==3892== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==3892== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info ==3892== Command: ./a.out ==3892== ==3892== Invalid write of size 2 ==3892== at 0x4005B4: main (in /home/indever/prg/C/public/a.out) ==3892== Address 0x520004c is 12 bytes inside a block of size 13 alloc'd ==3892== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299) ==3892== by 0x400597: main (in /home/indever/prg/C/public/a.out) ==3892== ==3892== Invalid read of size 1 ==3892== at 0x4C30BC4: strlen (vg_replace_strmem.c:454) ==3892== by 0x4E89AD0: vfprintf (in /usr/lib64/libc-2.24.so) ==3892== by 0x4E90718: printf (in /usr/lib64/libc-2.24.so) ==3892== by 0x4005CF: main (in /home/indever/prg/C/public/a.out) ==3892== Address 0x520004d is 0 bytes after a block of size 13 alloc'd ==3892== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299) ==3892== by 0x400597: main (in /home/indever/prg/C/public/a.out) ==3892== -> Hello, Habr! ==3892== ==3892== HEAP SUMMARY: ==3892== in use at exit: 0 bytes in 0 blocks ==3892== total heap usage: 2 allocs, 2 frees, 1,037 bytes allocated ==3892== ==3892== All heap blocks were freed -- no leaks are possible ==3892== ==3892== For counts of detected and suppressed errors, rerun with: -v ==3892== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)
== 3892 ==ãã¹ãŠã®ããŒããããã¯ã解æŸãããŸãã-ãªãŒã¯ã¯çºçããŸãã-ãªãŒã¯ã¯ãããŸãã ã ãã ããç®ãå°ãäžãã䟡å€ããããŸãïŒãã ããããã¯çµæã«éãããåºæ¬çãªæ å ±ã¯å°ãç°ãªããŸãïŒã
== 3892 ==ãšã©ãŒæŠèŠïŒ2ã€ã®ã³ã³ããã¹ããã3ã€ã®ãšã©ãŒïŒæå¶ïŒ0ãã0ïŒ
3ãšã©ãŒã 2ã€ã®ã³ã³ããã¹ãã ãã®ãããªåçŽãªããã°ã©ã ã§ã ã©ããã£ãŠïŒïŒ
ã¯ãããšãŠãç°¡åã§ãã å šäœã®ãããªãã¯ãã¯ãstrlené¢æ°ãè¡æ«æåã\ 0ããèæ ®ããªãããšã§ãã å ¥åè¡ã§æ瀺çã«æå®ãããŠããŠãïŒ#define HELLO_STRING "HelloãHabrïŒ\ N \ 0"ïŒãç¡èŠãããŸãã
ããã°ã©ã å®è¡ã®çµæããããããã«é«ãè¡-> HelloãHabrïŒ ç§ãã¡ã®è²Žéãªãã«ã°ã©ã€ã³ãã奜ãã§ã¯ãªãã£ãå Žæãšå Žæã®è©³çŽ°ãªã¬ããŒãããããŸãã ãããã®ç·ãç¬ç«ããŠèŠãŠãçµè«ãåºãããšãææ¡ããŸãã
å®éã«ã¯ãããã°ã©ã ã®æ£ããããŒãžã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
#include <stdio.h> #include <stdlib.h> #include <string.h> #define HELLO_STRING "Hello, Habr!\n" void main() { char *str = malloc(sizeof(char) * (strlen(HELLO_STRING) + 1)); strcpy(str, HELLO_STRING); printf("->\t%s", str); free(str); }
valgrindãééããŸãã
[indever@localhost public]$ valgrind --tool=memcheck ./a.out -> Hello, Habr! ==3435== ==3435== HEAP SUMMARY: ==3435== in use at exit: 0 bytes in 0 blocks ==3435== total heap usage: 2 allocs, 2 frees, 1,038 bytes allocated ==3435== ==3435== All heap blocks were freed -- no leaks are possible ==3435== ==3435== For counts of detected and suppressed errors, rerun with: -v ==3435== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
çŽ æŽãããã ãšã©ãŒã¯ãããŸãããå²ãåœãŠãããã¡ã¢ãªã®+1ãã€ããåé¡ã®è§£æ±ºã«åœ¹ç«ã¡ãŸããã
èå³æ·±ãããšã«ãã»ãšãã©ã®å Žåãæåãš2çªç®ã®ããã°ã©ã ã¯åãããã«åäœããŸãããçµäºæåãåãŸããªãè¡ã«å²ãåœãŠãããã¡ã¢ãªããŒãã§ãªãå ŽåãprintfïŒïŒé¢æ°ã¯ããã®ãããªè¡ãåºåããããšããã®è¡ã®-è¡æ«æåãprintfïŒïŒã®ãã¹ã«çŸãããŸã§ããã¹ãŠã衚瀺ãããŸãã
ãã ããïŒstrlenïŒstrïŒ+ 1ïŒã¯ãã®ãããªè§£æ±ºçã§ãã 2ã€ã®åé¡ã«çŽé¢ããŠããŸãã
- ãããŠãäŸãã°sïŒnïŒprintfïŒ..ïŒã§åœ¢æãããè¡ã«ã¡ã¢ãªãå²ãåœãŠãå¿ èŠãããå Žåã¯ïŒ åŒæ°ããµããŒãããŠããŸããã
- å€èŠ³ å€æ°å®£èšã®ããè¡ã¯ã²ã©ãèŠããŸãã mallocã®äžéšã®äººïŒchar *ïŒãããã©ã¹ã®äžã«æžãããã«åºå®ããããšãã§ããŸãã å®æçã«æååãåŠçããå¿ èŠãããããã°ã©ã ã§ã¯ããããšã¬ã¬ã³ããªãœãªã¥ãŒã·ã§ã³ãèŠã€ããããšã¯çã«ããªã£ãŠããŸãã
ç§ãã¡ãæºè¶³ãããå¿ãçãããœãªã¥ãŒã·ã§ã³ãèãåºããŸãããã
snprintfïŒïŒ
int snprintf(char *str, size_t size, const char *format, ...);
-é¢æ°-sprintfæ¡åŒµãæååããã©ãŒãããããæåã®åŒæ°ãšããŠæž¡ããããã€ã³ã¿ãŒã«åŸã£ãŠãããæžã蟌ã¿ãŸãã sprintfïŒïŒãšç°ãªãç¹ã¯ããµã€ãºã§æå®ããããããå€ãã®ãã€ããstrã«æžã蟌ãŸããªãããšã§ãã
ãã®é¢æ°ã«ã¯èå³æ·±ãæ©èœã1ã€ãããŸã-ãããã®å Žåã§ããçæãããæååã®ãµã€ãºãè¿ããŸãïŒè¡æ«æåãèæ ®ããã«ïŒã æååã空ã®å Žåã0ãè¿ãããŸãã
strlenã䜿çšããŠèª¬æããåé¡ã®1ã€ã¯ãsprintfïŒïŒããã³snprintfïŒïŒé¢æ°ã«é¢é£ããŠããŸãã æååstrã«äœããæžã蟌ãå¿ èŠããããšããŸãã æåŸã®è¡ã«ã¯ãä»ã®å€æ°ã®å€ãå«ãŸããŠããŸãã ãšã³ããªã¯æ¬¡ã®ããã«ãªããŸãã
char * str = /* */; sprintf(str, "Hello, %s\n", "Habr!");
åé¡ã¯ãæååstrã«å²ãåœãŠãã¡ã¢ãªéã決å®ããæ¹æ³ã§ããïŒ
char * str = malloc(sizeof(char) * (strlen(str, "Hello, %s\n", "Habr!") + 1));
-ä¹è»ã§ã¯ãããŸããã strlenïŒïŒã®ãããã¿ã€ãã¯æ¬¡ã®ããã«ãªããŸãã
#include <string.h> size_t strlen(const char *s);
const char * sã¯ãsã«æž¡ãããæååãå¯å€æ°ã®åŒæ°ãæã€æžåŒæååã§ããããšãæå³ããŸããã
ããã§ãäžèšã§èª¬æããsnprintfïŒïŒé¢æ°ã®æçšãªããããã£ã«å©ããããŸãã 次ã®ããã°ã©ã ã®ã³ãŒããèŠãŠã¿ãŸãããã
#include <stdio.h> #include <stdlib.h> #include <string.h> void main() { /* .. snprintf() , */ size_t needed_mem = snprintf(NULL, 0, "Hello, %s!\n", "Habr") + sizeof('\0'); char *str = malloc(needed_mem); snprintf(str, needed_mem, "Hello, %s!\n", "Habr"); printf("->\t%s", str); free(str); }
valgrindã§ããã°ã©ã ãå®è¡ããŸãã
[indever@localhost public]$ valgrind --tool=memcheck ./a.out -> Hello, Habr! ==4132== ==4132== HEAP SUMMARY: ==4132== in use at exit: 0 bytes in 0 blocks ==4132== total heap usage: 2 allocs, 2 frees, 1,041 bytes allocated ==4132== ==4132== All heap blocks were freed -- no leaks are possible ==4132== ==4132== For counts of detected and suppressed errors, rerun with: -v ==4132== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) [indever@localhost public]$
çŽ æŽãããã æã£ãŠããåŒæ°ã®ãµããŒãã snprintfïŒïŒé¢æ°ã®2çªç®ã®åŒæ°ãšããŠãŒããæž¡ããšããäºå®ã«ãããnullãã€ã³ã¿ãŒãžã®æžã蟌ã¿ãSeagfaultã«ã€ãªããããšã¯ãããŸããã ãã ããããã«ãããããããé¢æ°ã¯æååã«å¿ èŠãªãµã€ãºãè¿ããŸãã
ãããäžæ¹ã§ãè¿œå ã®å€æ°ãäœæããå¿ èŠããããèšèš
size_t needed_mem = snprintf(NULL, 0, "Hello, %s!\n", "Habr") + sizeof('\0');
strlenïŒïŒãããããã«æªãèŠããŸãã
äžè¬ã«ããã©ãŒãããæååã®æåŸã«æ瀺çã«ã\ 0ããæå®ãããšã+ sizeofïŒ '\ 0'ïŒãåé€ã§ããŸãïŒsize_t needed_mem = snprintfïŒNULLã0ãâ HelloãïŒ sïŒ\ N \ 0 âãâ HabrâïŒ ;ïŒãããããããã¯åžžã«å¯èœãšããããã§ã¯ãããŸããïŒæåååŠçã¡ã«ããºã ã«å¿ããŠãäœåãªãã€ããå²ãåœãŠãããšãã§ããŸãïŒã
äœãããå¿ èŠããããŸãã ç§ã¯å°ãèããŠãä»ãå€ä»£äººã®ç¥æµã«èšŽããæã ãšæ±ºããŸããã æåã®åŒæ°ãšããŠãã«ãã€ã³ã¿ãŒãã2çªç®ã®åŒæ°ãšããŠãŒããæå®ããŠsnprintfïŒïŒãåŒã³åºããã¯ãé¢æ°ã«ã€ããŠèª¬æããŸãã ãããŠãæã ã¯è¡ã®çµãããå¿ããªãã§ãããïŒ
#define strsize(args...) snprintf(NULL, 0, args) + sizeof('\0')
ã¯ããããã¯èª°ãã«ãšã£ãŠã¯ãã¥ãŒã¹ãããããŸããããCã®ãã¯ãã¯å¯å€æ°ã®åŒæ°ããµããŒãããçç¥èšå·ã¯æå®ããããã¯ãé¢æ°åŒæ°ïŒãã®å Žåã¯argsïŒãããã€ãã®å®åŒæ°ã«å¯Ÿå¿ããããšãããªããã»ããµã«äŒããŸãã
ãœãªã¥ãŒã·ã§ã³ãå®éã«ãã¹ãããŠã¿ãŸãããã
#include <stdio.h> #include <stdlib.h> #include <string.h> #define strsize(args...) snprintf(NULL, 0, args) + sizeof('\0') void main() { char *str = malloc(strsize("Hello, %s\n", "Habr!")); sprintf(str, "Hello, %s\n", "Habr!"); printf("->\t%s", str); free(str); }
valgrundããå§ããŸãã
[indever@localhost public]$ valgrind --tool=memcheck ./a.out -> Hello, Habr! ==6432== ==6432== HEAP SUMMARY: ==6432== in use at exit: 0 bytes in 0 blocks ==6432== total heap usage: 2 allocs, 2 frees, 1,041 bytes allocated ==6432== ==6432== All heap blocks were freed -- no leaks are possible ==6432== ==6432== For counts of detected and suppressed errors, rerun with: -v ==6432== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
ã¯ãããšã©ãŒã¯ãããŸããã ãã¹ãŠãæ£ããã§ãã ãããŠãvalgrindã¯å¹žãã§ãããã°ã©ããŒã¯ã€ãã«ç ãã«ã€ãããšãã§ããŸãã
ããããæåŸã«ãå¥ã®ããšãèšããŸãã ïŒåŒæ°ããã£ãŠãïŒä»»æã®è¡ã«ã¡ã¢ãªãå²ãåœãŠãå¿ èŠãããå Žåã¯ããã§ã«å®å šã«æ©èœããæ¢è£œã®ãœãªã¥ãŒã·ã§ã³ããããŸãã
ããã¯asprintfé¢æ°ã§ãã
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <stdio.h> int asprintf(char **strp, const char *fmt, ...);
æåã®åŒæ°ãšããŠãæååïŒ** strpïŒãžã®ãã€ã³ã¿ãŒãåãåããåç §è§£é€ããããã€ã³ã¿ãŒã«ã¡ã¢ãªãå²ãåœãŠãŸãã
asprintfïŒïŒã䜿çšããŠèšè¿°ãããããã°ã©ã ã¯æ¬¡ã®ããã«ãªããŸãã
#include <stdio.h> #include <stdlib.h> #include <string.h> void main() { char *str; asprintf(&str, "Hello, %s!\n", "Habr"); printf("->\t%s", str); free(str); }
ãããŠãå®éã«ã¯ãvalgrindã§ïŒ
[indever@localhost public]$ valgrind --tool=memcheck ./a.out -> Hello, Habr! ==6674== ==6674== HEAP SUMMARY: ==6674== in use at exit: 0 bytes in 0 blocks ==6674== total heap usage: 3 allocs, 3 frees, 1,138 bytes allocated ==6674== ==6674== All heap blocks were freed -- no leaks are possible ==6674== ==6674== For counts of detected and suppressed errors, rerun with: -v ==6674== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
ãã¹ãŠåé¡ãããŸããããã芧ã®ãšããããã¹ãŠã®ã¡ã¢ãªãããå€ãå²ãåœãŠãããallocsã¯2ã€ã§ã¯ãªã3ã€ã«ãªããŸããã 匱ãçµã¿èŸŒã¿ã·ã¹ãã ã§ã¯ããã®æ©èœã®äœ¿çšã¯æãŸãããããŸããã
ããã«ãã³ã³ãœãŒã«ã§man asprintfãšèšè¿°ãããšã次ã®ããã«è¡šç€ºãããŸãã
CONFORMING TO These functions are GNU extensions, not in C or POSIX. They are also available under *BSD. The FreeBSD implementation sets strp to NULL on error.
ããã«ããããã®æ©èœãGNUãœãŒã¹ã§ã®ã¿å©çšå¯èœã§ããããšãæããã«ãªããŸãã
ãããã«
çµè«ãšããŠãCã§ã®æååã®æäœã¯éåžžã«è€éãªãããã¯ã§ãããå€ãã®ãã¥ã¢ã³ã¹ããããŸãã ããšãã°ãã¡ã¢ãªãåçã«å²ãåœãŠããšãã«ãå®å šãªãã³ãŒããäœæããã«ã¯ãmallocïŒïŒã®ä»£ããã«callocïŒïŒé¢æ°ã䜿çšããããšããå§ãããŸããcallocã¯å²ãåœãŠãããã¡ã¢ãªããŒãã§è©°ãŸãããŸãã ããŠããŸãã¯ã¡ã¢ãªãå²ãåœãŠãåŸãmemsetïŒïŒé¢æ°ã䜿çšããŸãã ããããªããšãå²ãåœãŠãããã¡ã¢ãªã«å ã 眮ãããŠããã¬ããŒãžãããããã°æãããã³å Žåã«ãã£ãŠã¯æååã®æäœæã«è³ªåãåŒãèµ·ããå¯èœæ§ããããŸãã
ç§ã®ãªã¯ãšã¹ãã§æååã«ã¡ã¢ãªãå²ãåœãŠãåé¡ã解決ããç§ã®éŠŽæã¿ã®ããCããã°ã©ããŒã®åå以äžïŒã»ãšãã©åå¿è ïŒã¯ãæçµçã«ã³ã³ããã¹ããšã©ãŒãåŒãèµ·ãããŸããã ããå Žåã«ã¯-ã¡ã¢ãªãŒãªãŒã¯ãçºçããå Žåã§ãïŒãŸãã人ã解æŸããã®ãå¿ããïŒstrïŒã圌ãšã¯äžç·ã«ããªãïŒã å®éãããã¯ç§ãããªããä»èªãã ãã®åµé ç©ãäœæããããä¿ããŸããã
誰ãããã®èšäºã圹ç«ã€ããšãé¡ã£ãŠããŸãã ãªãç§ã¯ããããã¹ãŠãã©ãã«ã«å·»ã蟌ãã ã®ã§ãã-ç°¡åãªèšèã¯ãããŸãã ã©ãã«ãç¬èªã®åŸ®åŠãããããŸãã ãããŠãããªããç¥ã£ãŠããèšèªã®ç¹çŽ°ããããã°ããã»ã©ãã³ãŒãã¯è¯ããªããŸãã
ãã®èšäºãèªãã åŸãããªãã®ã³ãŒãã¯å°ãè¯ããªããšæããŸã:)
é 匵ã£ãŠãããã«ïŒ