2008/09/18


色々やってたら、出来た。これで が動く様になるのではないか!
地味な作業だったけど、以外と効果は大きいかも。今日は時間無いので明日以降にソース綺麗にしてオフィシャルにパッチを送ってみようかと思ってます。
ちなみにUNIXドメインソケットなmemcachedは動きません。(win32ですからね...)

mingw32でコンパイルすると、こんなソースがコンパイル実行出来ました。
#include <winsock2.h>
#include <memcached.h>
#include <stdio.h>

int main(void) {
    memcached_return rc;
    memcached_st *memc;
    char* value;
    int value_length = 0;
    int flags = 0;

    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
        return -1;
    }
    memc = memcached_create(NULL);;
    rc = memcached_server_add(memc, "127.0.0.1", 11211);
    printf("server add: %s\n", memcached_strerror(memc, rc));

    rc = memcached_set(memc, "test", 4, "example", 8, 0, 0);
    printf("set: %s\n", memcached_strerror(memc, rc));

    value = memcached_get(memc, "hoge", 4, &value_length, &flags, &rc);
    printf("get: %s\n", memcached_strerror(memc, rc));
    printf("test = %s\n", value);

    memcached_free(memc);
    return 0;
}
汚いソースを見たいという方はこの辺を...
Posted at by



2008/04/04


たぶん「ポインタ変数はポインタ型」で「配列変数は配列型」というイメージが持てないから。
C/C++のポインタの機能--変数の場所(アドレス) - builder by ZDNet Japan
int *n;
*n = 5; /* ポインタ変数nに値5を代入 */ 
現在は本文が修正されています。

C/C++のポインタの機能--配列との関係 - builder by ZDNet Japan

ポインタ変数と配列との深い関係を表す例を示そう。それは、配列の変数名をそのままポインタ変数名として扱えるということだ。


たぶん int *n;
こう宣言するから *n = 5;
こうしたくなる訳で int* n;
こう宣言すれば、もしくは typedef int * int_ptr
こうしておいて int_ptr n;
こう宣言すれば *n = 5;
こんな事が間違ってる事に気付くかな?
int m[] = {1,2,3,4};
int *n;
n = m;
ここでいうnへのmの代入は、mの先頭アドレスをnが指しているだけなのです。ポインタは「指し棒」!配列はメモリのかたまり!
※最近のC言語の本って「先頭アドレス」って表現あまり見ない気がする。

ちなみに、間違っても char* n, m;
m = "Hello, World";
とか #define char_ptr char *
...
char_ptr n, m;
m = "Hello, World";
しちゃ駄目(typedef使ってね)。

ちなみに...
char *s = "abc";
char s[] = "abc";
の話も前者が「ポインタ型」、後者が「配列型」と考えればいい。
つまり typedef char char4[4];
char4 n = "abcef"; // char[4]型変数をchar[6]で初期化
こうすると、コンパイラによっては警告出力してくれる訳です。
Posted at by



2008/03/31


コンパイルは通るだろうけど、ちょっと本文から直してほしいですね。影響力のある場所でしかも「推薦する」なんてリンクが付いている状態で放置は間違いを広めてしまうよ。
C/C++のポインタの機能--参照渡しのような処理 - builder by ZDNet Japan
で、Electric Fenceの紹介につなげる記事にしようと思ったのですが
electric-fence-win32 - Google Code
Electric Fenceのwin32版なんてものを見つけてしまった。
てっきりUNIX版と同様、リンクすれば動くと思って色々試したけど、どうやらそうじゃないみたい。
//#include <efence.h>
#include <stdio.h>
int main( void ) {
    char *a = (char*)malloc(12);
    a[ 0] = 'H';
    a[ 1] = 'e';
    a[ 2] = 'l';
    a[ 3] = 'l';
    a[ 4] = 'o';
    a[ 5] = ',';
    a[ 6] = ' ';
    a[ 7] = 'W';
    a[ 8] = 'o';
    a[ 9] = 'r';
    a[10] = 'l';
    a[11] = 'd';
    a[12] = '\0';
    return 0;
}
オーバーランを検知してくれなかった。README.win32によると

Since you need to modify your own project anyway, simply add efence.c, page-win32.c, and print.c to your project.

と書いてありました。てっきりスタートアップルーチンを入れ替えてくれてくれる物かと思って少しだけ期待してしまいました。
mingw32ならば Index: Makefile
===================================================================
--- Makefile    (revision 7)
+++ Makefile    (working copy)
@@ -9,7 +9,7 @@
 MAN_INSTALL_DIR= /usr/man/man3
 
 PACKAGE_SOURCE= README libefence.3 Makefile efence.h \
-   efence.c page.c print.c eftest.c tstheap.c CHANGES COPYING
+   efence.c page-win32.c print.c eftest.c tstheap.c CHANGES COPYING
 
 # Un-comment the following if you are running HP/UX.
 # CFLAGS= -Aa -g -D_HPUX_SOURCE -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
@@ -26,7 +26,7 @@
 # as well if using Sun's compiler, -static if using GCC.
 # CFLAGS= -g -Bstatic -DPAGE_PROTECTION_VIOLATED_SIGNAL=SIGBUS
 
-OBJECTS= efence.o page.o print.o
+OBJECTS= efence.o page-win32.o print.o
 
 all:   libefence.a tstheap eftest
    @ echo
@@ -63,7 +63,7 @@
 
 tstheap: libefence.a tstheap.o
    - rm -f tstheap
-   $(CC) $(CFLAGS) tstheap.o libefence.a -o tstheap -lpthread
+   $(CC) $(CFLAGS) tstheap.o libefence.a -o tstheap -lpthreadGC2
 
 eftest: libefence.a eftest.o
    - rm -f eftest
こんな風に修正して mingw32-make CC=gcc libefence.a でlibefence.aが出来上がり、上のソースの冒頭の「//」を外して #include <efence.h>
#include <stdio.h>
int main( void ) {
    char *a = (char*)malloc(12);
    a[ 0] = 'H';
    a[ 1] = 'e';
    a[ 2] = 'l';
    a[ 3] = 'l';
    a[ 4] = 'o';
    a[ 5] = ',';
    a[ 6] = ' ';
    a[ 7] = 'W';
    a[ 8] = 'o';
    a[ 9] = 'r';
    a[10] = 'l';
    a[11] = 'd';
    a[12] = '\0';
    return 0;
}
あぶないコードに修正した後 gcc -g -o dame.exe dame.c -lefence とすれば、efenceビルドされたdame.exeが出来上がり実行すると、正しくクラッシュしてくれる。gdbで確認すれば
C:¥temp¥electric-fence-win32>gdb dame.exe
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-mingw32"...
(gdb) run
Starting program: C:¥temp¥electric-fence-win32/dame.exe
...
Program received signal SIGSEGV, Segmentation fault.
0x00401396 in main () at dame.c:17
17              a[12] = '\0';
(gdb)
とクラッシュ場所も分かると。でもUNIX版みたくソースは修正したくないなぁ。
あとmallocでなく char a[12];
とした場合にクラッシュしてくれないのならば、威力半減ってところか。
Posted at by