1read 100read
2012年1月2期プログラム6: C言語なら俺に聞け(入門編)Part 95 (702) TOP カテ一覧 スレ一覧 2ch元 削除依頼
・ 次のスレ
7: Rubyについて Part46 (323)
8: Excel VBA 質問スレ Part22 (968)
9: Perlについての質問箱 50箱目 (191)
10: 【SL4】Windows Phone 7 アプリ開発スレ Part3【XNA】 (128)

C言語なら俺に聞け(入門編)Part 95


1 :12/01/13 〜 最終レス :12/01/27
C言語の*入門者*向け解説スレッドです。
★前スレ
C言語なら俺に聞け(入門編)Part 94
http://toro.2ch.net/test/read.cgi/tech/1324648274/
★過去スレ
http://makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
★教えて欲しいのではなく宿題を丸投げしたいだけなら
  ↓宿題スレ↓へ行ってください。
C/C++の宿題片付けます 155代目
http://toro.2ch.net/test/read.cgi/tech/1325685876/
★C++言語については避けてください。C++対応明記スレへどうぞ
★分からない事をなるべく詳しく書いて下さい。
★ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
★開発環境や動作環境も晒すと答えが早いかもしれません。
★質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
長くなりそうなコードはcodepadに貼り付けてもいいでしょう
http://codepad.org/

2 :
野田改造内閣に早速疑惑浮上
@aritayoshifu 有田芳生
捜査当局が内偵を続けている農水疑惑。詳細な怪文書まで出回っている。3億円の
行方はどこに?
@minorucchu ジャーナリスト 田中稔
野田改造内閣を揺るがす、農水省3億円スキャンダルの怪文書。二人の議員名が浮上。
34分前 webから
https://twitter.com/#!/minorucchu/status/157687110562881537
鹿野と筒井らしい
自公は問責も視野に調査開始だって

3 :
オイ俺のコピペ脳!まで読んだ。

4 :

int main() {
 char* str1[10];   //定義しただけで初期化していない。つまり文字列は格納されていない。
 func1( &str );
}
void func1( char* str ) {
 char* inStr;
 str = "test data";
 return ;
}
 
質問なんだが。
なぜ、きちんとstrに文字データが格納されるんだろうか?

5 :
タブスペースで書き込んじまった
int main() {
 char* str1[10];   //定義しただけで初期化していない。つまり文字列は格納されていない。
 func1( &str );
}
void func1( char* str ) {
 char* inStr = "test";
 inStr = anotherFunc() ;
 str = inStr + 1 ;
 return ;
}
 
質問なんだが。
なぜ、きちんとstrに文字データが格納されるんだろうか?
main 関数でstr のポインタ領域は確保されているが、その参照先の文字列領域は未確保。
func1にとんだ先では、自動変数inStr に文字列が格納されており、そのポインタを渡すことでstrの中身に具体的なポインタが入る。
func1内では、str のポインタの指し示す先は自動変数inStrと同じポインタであり、参照できて当然。
ところが、return すると、自動変数inStr の内容はスタックを戻すことにより開放されている。
return された後にmainにてstrを参照しても全く問題ないし、キチンと値が格納されている。
値が参照できるのは、たまたまナノか?
この操作は問題ない?

6 :
まずはコンパイルが通るか自分で確認してから書き込め

7 :
最初のスタックへのアドレスがまずさ迷い人に成って5ではfunc1のリテラルも全く無意味になって更にアナザの返値の先頭バイトまで無意味に成ってる。

8 :
>>6
あいよ。
int main(){
 char* str[10];   //定義しただけで初期化していない。つまり文字列は格納されていない。
 func1( str );
}
void func1(char* str[] ) {
 char* inStr;
 inStr = anotherFunc() ;
 str[1] = inStr + 1 ;
 return ;
}
char* anotherFunc(){
 return (char*)"test";
}

9 :
>int main() {
> char* str1[10];   //定義しただけで初期化していない。つまり文字列は格納されていない。
>
> func1( &str );
>}
変数名ちゃうやん。
>void func1( char* str ) {
型ちゃうやん。(char ** → char *)

10 :
>>7
>更にアナザの返値の先頭バイトまで無意味に成ってる
戻り値として、「est」が欲しいのでそうなってる。

11 :
str[1]="test"+1;

12 :
>>11
anotherFunc の return は、例えば「Content-Type: application/x-javascript」
その中で「application/x-javascript」を取り出したい。

13 :
char* anotherFunc(){
 return (char*)"test";
}
がもし、
char* anotherFunc(){
 return (const static char*)"test";
}
なら、BSSなり、テキスト領域なりに格納されると思う。
テキスト領域かな?
でも
char* anotherFunc(){
 ・・・
 何がし処理
 ・・・
 return buf ; //bufには「Content-Type: application/x-javascript」文字列が格納
}
であるならコンパイルエラー(local address云々)
ここまでなら分かる。

14 :
"test"はプログラムをメモリ上に読み込んだ時点で確保されてる。
開放されるのはプログラム終了時。
return (char*)"test";

char *inStr = "test";
return inStr;
も、書き込みをしなければ問題ない。
但し
char inStr[] = "test";
return inStr;
は駄目。

15 :
ところが、>>8 における inStr はfunc1のスタックに積まれる。
いくら、str[1]にポインタを代入したところで、参照しているのはfunc1のスタック上にあるinStrのアドレスである。
func1がリターンしてしまうと、スタックは破棄( ただ単にゼロクリアしていないだけ)な気がする。
結局うまく言っているように見えるのはスタックが破壊されていないから?かな、と。

16 :
>>14
返信ありがと。
str[1]に書き込んでmainで参照するにはどうするのが良い?

17 :
ならないよ。
>8 の inStrはいわばメモ書き。
"test"の場所が書かれてるだけ。
str[1]に内容をコピー(1足してるけど)した後に消える。
住所書かれてるメモ紙を捨てたらその住所が消滅するわけじゃあるまい?

18 :
あ、
念のため・・・
char* str[10] は、10個の不定長の文字列を格納する10個のポインタです。
最終目的は、sub関数から不定長の文字列を設定したい、と言うことです。

19 :
>>17
最終的に聞きたいのは、スタティックなリテラル値ではなく、ダイナミックな変数の値です。
つまり、
inStrの具体的な値を、str[1]に入れ込むためにはどうしたらよいのか?と言うことです。

20 :
【話題】女子にイラッとされる「理系男子特有の話し方」9パターン★2
【1】「要するに」と他人の話もまとめてしまう
【2】「違う」と小さな間違いでもいちいち訂正する
【3】「化学反応だから」などロマンチックなことにも根拠を述べる
【4】「仮に」など自分の専門分野でたとえたがる
【5】「具体的には?」と曖昧な表現でなく数字を知りたがる
【6】「データがあるから」と他人の意見を受け入れない
【7】「わかる?」と難しい説明の後で上から目線の確認をする
【8】「ありえない」など決めつけて断言する
【9】「だから?」とオチを先に聞きたがる
要するに馬鹿しか女子とはお話出来ないということだな

21 :
1, 2, 7, 8は理系文系関係なく糞爺にも当てはまるw

22 :
>19
>8 の
>str[1] = inStr + 1 ;
でいいんじゃないの?

23 :
>>22
うむむ。
分からないのは、
「inStr+1」で指定されたアドレスは、func1がreturnされると開放されるメモリアドレスじゃないですか?
そうすると、そのアドレスを入れ込んだstr[1]の内容(=アドレス)も開放されてしかるべきアドレスじゃないかと?

24 :
17を100回読め

25 :
コンパイルエラーでできないんだけれども、こんなことをやりたいんだと言うことです。
*( str[1] ) = *( inStr + 1) ;

26 :
>>24
20回読みましたデス。足りないかな?
スタティックなリテラル値の話ではなく、自動変数に格納されている値を戻したいと言うことですが・・・
戻すとき、リターン値はエラーコードで使用されていますのでリターンで戻すのは不可です。
なのでfunc1にポインタで渡して、その内容を更新したい、ということです。
もう20回読んでみます。

27 :
後だしと言われるのを避けるために、実際のコードの説明をしますが、
実際にはfunc1 には構造体を渡しています。
正確には構造体のアドレスを渡してます。
構造体は
typedef struct s{
char* field[MaxHeaderNum];
char* attrib[MaxHeaderNum];
}S;

28 :
こうか?
str[1] = (char *)malloc(strlen(inStr + 1)+1) ;
if(!str[1]){
/*エラー処理*/
}
strcpy( str[1] , inStr + 1);

29 :
>>28
すんばらしい。
そういうことです。
はじめはそのように書いていたのですが、
非常に頻繁に呼ばれることと、
mainのなかでいつfreeすればよいのかが不定であることや、
関数を変にまたがってしまう、
などなどの複雑な問題により諦めてしまいました。
で、コードをシンプルにする方法でのアプローチでコーディングしなおしてます。
ヒープを使わなければ無利なのでしょうか?

30 :
とりあえず
char* str[10]
をゼロクリアしてから使え。
あとは終了時とmallocする前にNULLで無ければfreeするような処理書いとけばいいんじゃね?

31 :
>>30
だんけ
ってことは、>>8はたまたまうまく行っているだけってことかな?

32 :
長引いてるな…
>スタティックなリテラル値の話ではなく、自動変数に格納されている値を戻したいと言うことですが・・・
自動変数に〜というなら、malloc でヒープに領域を確保して、外部で解放するしかない。
自動で解放して欲しいのなら、C++ に行ってデストラクタなり std::string なりに頼る。
>>8 はスタティックなリテラルのポインタを返してるので、たまたまではなく正常に動作する。ただし貴方の求めているものではない。

33 :
メールとかの通信関係の処理か?
クラス化の設計とか楽しそうだなぁ。

34 :
>>32
ありがと。
参考になります。
>>33
bingo
HTTPだけど。
移植性を考えてて、ANSI-Cベースで書いているところが、またそれはそれで、制限が多いw

35 :
>>15
> 参照しているのはfunc1のスタック上にあるinStrのアドレスである。
これが間違えていることには気づいているのだろうか
inStrのアドレスは&inStrな。

36 :
>>35
宣言が、
char* inStr だけれども?

37 :

反日ネット工作員
朝日新聞社→社員約300人
民主党とその取り巻きの資金が入った反日工作会社→数社約450人
朝日新聞の社員は捕まった49歳の編集者を含め新聞記事を書く合間に2chを荒らしている程度とみられているが
民主党が用意した反日工作会社はほぼ24時間体制で工作を行っている
工作範囲は民主党が予め工作費を流している2ch、ニコニコ動画を中心にyoutube、個人のブログなどである。

38 :
>19
>inStrの具体的な値を、str[1]に入れ込むためにはどうしたらよいのか?と言うことです。
「inStrの具体的な値」と言ったらinStrに代入されてる"test"のアドレス値のことだろ。
それが
>28
が正解というなら
「inStrのポインタが示す先の文字列をコピーして、str[1]に入れ込むためにはどうしたらよいのか?」
と言うべきだろ。
まぁ、そう言えるぐらい理解できてるなら質問もしてこないだろうが。

39 :
>>36
だから?

40 :
sizeof(char *) == sizeof(int)
なら
void func1(char* str[] ) {
 int inStr;
 inStr = (int)anotherFunc() ;
 str[1] = (char *)(inStr + sizeof(char)) ;
 return ;
}
としても同じ結果なんだよ。

41 :
intptr_t 使えよ

42 :
>>40
日記ならチラシに

43 :
別名便所の壁の2chがチラシより上とな!?

44 :
便所の壁はみんなの目に触れるからな

45 :
都内じゃ1500枚ほどチラシが貼られたらしいな。

46 :
>>38
>「inStrのポインタが示す先の文字列をコピーして、str[1]に入れ込むためにはどうしたらよいのか?」
コピーして
の部分が全く違う。
コピーしてよいのなら、解決法はいくつでもある。

47 :
>46
>28
>strcpy( str[1] , inStr + 1);
コピーしてるやん。
違うというなら正しいソース書いてみてよ。

48 :
>>47
多分、言いたいことの1/1000も伝わっていないんだと思う。
バッファから下ろしてきたデータは一時的にしかるべき場所に「コピーして」配置される。
俺の言っているのは、
そのしかるべき場所のポインタを渡すだけにしたいんだが、何とかならんのんかの?
という質問だが、
君は「さらに」、コピーしたらええやん、
と言っている。

49 :
その「しかるべき場所」はグローバルか何かで確保されてたり消える心配がないのであれば
そのポインタを渡すだけでいいじゃん

50 :
ところで、そもそも、コピーができるのか?という問題も、ある。
構造体は
typedef struct s{
 char* field[MaxHeaderNum];
 char* attrib[MaxHeaderNum];
}S;
ストリームデータがこのようになっているとき、(¥区切り文字)
aaaaaaa\bbbbbbbbbb\cccc\dd\eeeeeeeeeee\
     ↑       ↑  ↑ ↑        ↑
attrib[1] attrib[2] attrib[3] attrib[4] attrib[5]
のポインタが入る。
コピーできるん?????
コピーじゃなくて、もう一度strstrあたりできりなおさんとまずくない?????
ま、さくっとコピーできるんだったら、謝る

51 :
何を何にコピーすることを言ってるのか?
区切り文字が'\'というのは例として挙げただけ?

52 :
>>49
コーディング規約により、グローバル宣言ができないんですヨ
・局所的にしか利用されず
・他スレッドからの参照に問題あり
・アクセスコントロールに関与する
・マルチスレッド対応の場合
などなど。

53 :
>>51
そ。
\r\n = ¥
としただけ

54 :
仕事上のコーディング方法を2chで質問かよwww

55 :
みんなすげーな
オレには何を言いたいのか全然分からん

56 :
民主党が惨敗した参院選直前の政党支持率(2010年7月11日投票)
FNN 2010年7月4日
民主党 29.9% 自民党 16.3%
ttp://sankei.jp.msn.com/politics/policy/100706/plc1007060530003-n1.htm
ttp://www.fnn-news.com/archives/yoron/inquiry100705.html
マスコミに、ダマされるなよ。

57 :
この子の関わったソフトが載った製品は買いたくないと思ってしまうな
@>何を何にコピーすることを言ってるのか? への回答は?
A「しかるべき領域」はスタック上?ヒープ上?それ以外?スタック上ならほぼコピーするしかない
B「しかるべき領域」は書き換えてもよい?書き換えたらダメなのであればさらにコピーするしかない

58 :
>>54
チートツールなんだが、なぜに仕事だと思うのかなぁwww

59 :
>>57
>この子の関わったソフトが載った製品は買いたくないと思ってしまうな
売り出されたら驚いちゃゃう?
>@>何を何にコピーすることを言ってるのか? への回答は?
機種依存文字はどうかと思うけど。
コピーと言われたから、それを使っただけ。
>A「しかるべき領域」はスタック上?ヒープ上?それ以外?スタック上ならほぼコピーするしかない
スタック上。
main関数のスタックに積んでいればOKでしょ?
違うの???
>B「しかるべき領域」は書き換えてもよい?書き換えたらダメなのであればさらにコピーするしかない
書き換えても良いの意味が分からん。
書き換えたらダメってことは、参照もダメってこと???
意味が不明です。

60 :
>>59
お前が意味不明だな。
手繰るの面倒だからここでもう一度整理して新規に質問しなおせ。

61 :
>>60
君のおかげで整理できたよ。
聞きたい内容は、
呼び出し先の呼び出し先から、大元のスタックにある文字列を直接変更できるか?
ってこったな。
孫関数には、ポインタのポインタなら渡せる、と言う条件でな。

62 :
>>61
その質問の答えは、できる、だ。

63 :
細かい条件を列挙する。
・データはストリームで落とされる。
・孫関数にはポインタのポインタが渡される
・文字列の長さは不定長
・区切り文字がある文字列
・ストリームは、孫関数で処理される
この条件で親のスタックに詰まれた文字列を孫から操作できるかどうか?
んだな。

64 :
ちゃんと質問できるようになるまで何年もかかりそうだな
義務教育の間何やってたんだか

65 :
おっと。
追加があった
・データはストリームで落とされる。
・孫関数にはポインタのポインタが渡される
・文字列の長さは不定長
・区切り文字がある文字列
・ストリームは、孫関数で処理される
・staticは使えない

66 :
>>64
まあ、そんなことより、
>>52が仕事上のタスクだと思う方が驚きだけど。
指示されないと何もできないんかなぁ。
もしくは何でもグローバル宣言すりゃいいと思っているのかなぁ。
普通に個人のコーディング規約に含まれる常識的な内容だと思っていたんだが、これも違うのか?

67 :
>>66
>>65 を読む限りお前の考えたものではないだろうし
バカみたいな社内用語?で伝わると思ってるのがおかしい

68 :
>>65
わけのわからない条件は関係なく、元のスタック上の文字列のポインタが
わかるなら当然できるだろ。
なんでできないとか思うんだろ。
ちなみに、スタックとかストリームとか、Cには関係ないから。

69 :
>>68
ストリームデータは軽く64kを超えるんだが、
mainで
char streamData[131072]
とか宣言しちゃうの?
スマートじゃない気がするけどw
後々func1がスレッドで動くようになるんだし、mainがdllmainになるんだが、
どう見てもそりゃスマートとは言いがたいと思うんだけど、どうだろうか?

70 :
>>67
こちとら、素人だし、
チートツールの作成を企業が許可するとも思えんし、
>普通に個人のコーディング規約に含まれる常識的な内容
だと思うんだけど、違うのか?

71 :
整理して質問しろと言っただろ。
> 呼び出し先の呼び出し先から、大元のスタックにある文字列を直接変更できるか?
できる。
もう一度だけチャンスをやる。
整理して1レスで質問しろ。

72 :
>>61できたよhttp://codepad.org/Q33HWUEa

73 :
>>70
チートツール作るなんてことを言ってるバカに協力しねーよ

74 :
>>71
>できる。
こういうことだろ?
>>69

75 :
どういうことだよ。
お前、頭腐ってるわ。

76 :
o君の考えるスタックとは何を指しているのかね?

77 :
>>72
f2を実行しないと、str[]の大きさが分からないんだけど、それでも大丈夫ってこと?
少なくとも512byteは確実に超えるんだけど。

78 :
ここまで日本語が通じないのも珍しいな。
いや、そうでもないか。

79 :
>>75
>>69以外に方法があるなら、丁重に謝るよ。

80 :
>>79
お前の思い込みなんて人にはわからないんだよ。
だからお前のことを何も知らない普通の人間にわかるように整理して
1レスにまとめて質問してみろよ。

81 :
>>76
関数が呼び出されたことにより確保される、SP、ReturnAddressと自動変数のかまたり

82 :
スタックのサイズが心配ならスタックを拡張するなりヒープを使うなり
すればいいだけだろ。

83 :
>>80
あいよ。
聞きたい内容は、
呼び出し先の呼び出し先から、大元のスタックにある文字列を直接変更できるか?
条件は次の通り
・データはストリームで落とされる。
・孫関数にはポインタのポインタが渡される
・文字列の長さは不定長
・区切り文字がある文字列
・ストリームは、孫関数で処理される
・staticは使えない

84 :
だから、ストリームて何だよ。
思い込みハゲしいなまったく。

85 :
文字列を直接変更できるかどうかに長さや区切り文字は関係ないだろ。

86 :
>>84
不定長のデータ、でよいよ。

87 :
>>85
>>72のコードで、512byteのデータをどうやって変更するの?

88 :
またか。
その512byteのデータと>>72がどう関係するんだよ。

89 :
>>88
void f2(char* str){
str[500]='\r';
str[501]='\n';
}
ができるんだったら、何も言わんよ

90 :
>>89
じゃぁ何も言うな。

91 :
ああ、
void f2(char* str){
str[131070]='\r';
str[131071]='\n';
}
ができるんだったら何も言わんよwww

92 :
>>90
エラーが出るんですけどwww

93 :
そりゃそうだわな。
str[10] と宣言しているのに、
str[131070]にアクセスしているんだもんね。
>>90は、そんなことも分からないの?

94 :
何も言うなと言ってるだろ。

95 :
>>94
君は、回答する前に、こっちを読んで勉強した方が良いと思うよ。
http://www.kumei.ne.jp/c_lang/intro/no_07.htm
宣言した数より大きな領域にアクセスさせるのは危険だよ。
書き込みなんかしたら、スタック壊しちゃうからね。
気をつけたほうが良いよ。

96 :
また、えらく拗らせちゃってるんだね。
スタックのサイズが心配なら512KBをヒープに確保してそれを渡せばいいだけだろ。
まわりの人も大変だろうな。

97 :
無能な働き者ってこの質問主の様な奴の事なんだろうな。

98 :
>>95
>宣言した数より大きな領域にアクセスさせるのは危険だよ。
常識で分かることは言う必要がない。

99 :
無能な働き者。これは処刑するしかない。

100read 1read
1read 100read
TOP カテ一覧 スレ一覧 2ch元 削除依頼
・ 次のスレ
7: Rubyについて Part46 (323)
8: Excel VBA 質問スレ Part22 (968)
9: Perlについての質問箱 50箱目 (191)
10: 【SL4】Windows Phone 7 アプリ開発スレ Part3【XNA】 (128)