C言語:メモリの確保

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
やっくん

C言語:メモリの確保

#1

投稿記事 by やっくん » 15年前

メモリの確保について教えていただけないでしょうか。

言語:C言語
コンパイラ:gccまたはVC++2008


char *p[10] = {"str1"."str2","str3"};

この場合はコンパイラが自動的にポインタ変数のメモリを静的確保していて、

char *p[10];

この場合はポインタ変数のメモリが確保されないので上と同じような動作を作りたい場合は自分でメモリを動的に確保して使用する、と思っておりました。

しかし、

p = (char**)calloc(3, sizeof(char*));

このような記述をしてもコンパイラに通りません。

ただ単に p と表記した場合はchar型ポインタのポインタになっていると思っていましたが、違うのでしょうか?

もし、違うのならこの場合どのようにメモリを確保することが正しいでしょうか?

いつもは以下のように行っていますが、上の方法でできないか気になったのでよろしくお願いします。
int i;
char **p;
p = (char **)calloc(3, sizeof(char*));
for(i = 0; i < 3; i++)
    p = (char *)calloc(10, sizeof(char));


画像

box

Re:C言語:メモリの確保

#2

投稿記事 by box » 15年前

> 上と同じような動作を作りたい場合は自分でメモリを動的に確保して使用する、と思っておりました。

大きな間違いです。
上と同じようにしたければ、

p[0] = "str1";
p[1] = "str2";
p[2] = "str3";

と書くだけです。
malloc系の関数を使う必要など、どこにもありません。

上と下の違いは、
上:配列の定義時に、初期化も行なっている
下:配列を定義しているだけで、初期化はしていない
です。

やっくん

Re:C言語:メモリの確保

#3

投稿記事 by やっくん » 15年前

boxさん返信ありがとうございます。

char *p[10];

と宣言した場合、メモリはどのように確保されているのかがわかりません。

boxさんの記述を見ると、まだこの時点ではメモリ確保はされておらず、『コンパイル時に値を代入する処理を行っている際に随時メモリは確保されている』ということでいいでしょうか?

また、

char *p[10];

この記述でプログラム実行中に動的メモリを確保するにはどうすれば良いでしょうか?

実行中にmallocなどを使わずに

p[0] = "str1";
p[1] = "str2";
p[2] = "str3";



とするのはメモリ領域が取られてないので不可能ですよね。

box

Re:C言語:メモリの確保

#4

投稿記事 by box » 15年前

> char *p[10];
>
> と宣言した場合、メモリはどのように確保されているのかがわかりません。

どうしてですか?
配列の要素がchar型へのポインターである、というだけで、
int p[10];
などのような、配列の要素がポインター以外の場合と本質的には全く同じです。

> boxさんの記述を見ると、まだこの時点ではメモリ確保はされておらず、『コンパイル時に値を代入する処理を行っている際に随時メモリは確保されている』ということでいいでしょうか?

いいえ。間違いです。
char *p[10];
と書いた時点で、char型へのポインター10個分を要素とする配列を
メモリーに確保します。

> 実行中にmallocなどを使わずに
>
> p[0] = "str1";
> p[1] = "str2";
> p[2] = "str3";
> ・
> ・
>
> とするのはメモリ領域が取られてないので不可能ですよね。

できますよ。実験してみてください。
ていうか、上で書いたとおり、

int p[10];
と定義だけしておいて、実行中に
p[0] = 123;
p[1] = 456;
p[2] = 789;
のように書くのと本質的には同じ話。 画像

やっくん

Re:C言語:メモリの確保

#5

投稿記事 by やっくん » 15年前

ありがとうございます。

すみません、大きな勘違いをしておりました。

char *str[10];

をポインタの配列と捉えていませんでした(^^;

> p[0] = "str1";
> p[1] = "str2";
> p[2] = "str3";

しかし、このようにするには以下のようにメモリ確保は必要ないのでしょうか?

p[0] = (char *)calloc(256, sizeof(char));
p[1] = (char *)calloc(256, sizeof(char));
p[2] = (char *)calloc(256, sizeof(char));

たかぎ

Re:C言語:メモリの確保

#6

投稿記事 by たかぎ » 15年前

> しかし、このようにするには以下のようにメモリ確保は必要ないのでしょうか?

ありません。

やっくん

Re:C言語:メモリの確保

#7

投稿記事 by やっくん » 15年前

たかぎさん、返信ありがとうございます。

>ありません。
代入文で文字列を代入したときはコンパイラが自動的にメモリ確保をしてくれてると解釈しました。

しかし、以下のソースをコンパイルし実行するとエラーとなります。
ここでは文字を代入ではなくstrcpyを用いています。
この場合は確保する必要がありますか?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    int i;
    char *str[10];

    //str[0] = (char *)calloc(10, sizeof(char)); // これを入れたら通る
    //str[1] = (char *)calloc(10, sizeof(char));  // これを入れたら通る
    //str[2] = (char *)calloc(10, sizeof(char));  // これを入れたら通る
    
    strcpy(str[0], "str1");
    strcpy(str[1], "str2");
    strcpy(str[2], "str3");

    printf("str[0] = %s\n", str[0]);
    printf("str[1] = %s\n", str[1]);
    printf("str[2] = %s\n", str[2]);

    return 0;
}

たかぎ

Re:C言語:メモリの確保

#8

投稿記事 by たかぎ » 15年前

> 文字列を代入したときは

「文字列リテラル」を代入した場合です。

> この場合は確保する必要がありますか?

こちらは当然何らかの方法でメモリを確保しなければなりません。

やっくん

Re:C言語:メモリの確保

#9

投稿記事 by やっくん » 15年前

boxさん、たかぎさん、ありがとうございました。

解決することができました。

閉鎖

“C言語何でも質問掲示板” へ戻る