アプリ版:「スタンプのみでお礼する」機能のリリースについて

c言語のダブルポインタ(char **)の引数渡しで困っています。
ワーニングが取れず、無視して実行するとセグメンテーション違反
となります。

ワーニングを取る方法をご存じないでしょうか?
もしくは言語仕様、gcc仕様が要因でしょうか?

バージョンはgcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)です。

001 void func(char **p1)
002 {
003 static char *s="AAA";
004 **p1 = s;
005 }
006 int main(void)
007 {
008 char *q1;
009 func(&q1);
010 return(0);
011 }

$ cc -Wall -o pp pp.c
pp.c: In function ‘func’:
pp.c:5: 警告: assignment makes integer from pointer without a cast

実行すると004行目で 'セグメンテーション違反です (core dumped)'となります。
004行目を *p1 = s; にするとワーニング無しとなり、
問題無くcall側のq1に先頭アドレスがセットされますが、
何か納得がいきません。

ちなみに、最初のcore吐きプログラムのアセンブルリストは
以下のようになります。
(*)位置で変なコードとなっていまが、ワーニングが出て
いるので当然なのかもしれません。

(gdb) disass
Dump of assembler code for function func:
0x08048354 <func+0>: push %ebp
0x08048355 <func+1>: mov %esp,%ebp
0x08048357 <func+3>: mov 0x8(%ebp),%eax
0x0804835a <func+6>: mov (%eax),%edx
0x0804835c <func+8>: mov 0x8049560,%eax
*0x08048361 <func+13>: mov %al,(%edx)
0x08048363 <func+15>: pop %ebp
0x08048364 <func+16>: ret
End of assembler dump.

そして 004行目を *p1 = s;にした場合が以下となります。
想定通りのコードですが、何故なのかわかりません。

Dump of assembler code for function func:
0x08048354 <func+0>: push %ebp
0x08048355 <func+1>: mov %esp,%ebp
0x08048357 <func+3>: mov 0x8049560,%edx
0x0804835d <func+9>: mov 0x8(%ebp),%eax
0x08048360 <func+12>: mov %edx,(%eax)
0x08048362 <func+14>: pop %ebp
0x08048363 <func+15>: ret
End of assembler dump.

A 回答 (3件)

**p1 はchar型でsはポインタ型なのだから当然では?

    • good
    • 0
この回答へのお礼

ありがとうございます。
久々のC言語で迷路に入っていました。
助かりました。

お礼日時:2009/07/03 01:07

wildcat-ypさんと同じ意見です。



char **p1 と宣言しているため、
p1 → char型データのポインタのポインタ
*p1 → char型データのポインタ
**p1 → char型データ

char *s と宣言しているため、
s → char型データのポインタ
*s → char型データ
    • good
    • 0
この回答へのお礼

ありがとうございます。
助かりました。

お礼日時:2009/07/03 01:03

そもそも「何がしたくて **p1 = s; って書いている」の?


どう考えてもこれが「正常」とは思えないよね.

この回答への補足

わざわざ回答して下さるのは結構ですが、
わからないなら見下したような回答は避けて下さい。

老婆心での忠告です。
感謝して下さいね。

補足日時:2009/07/03 01:04
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!