0

私は最近、Cの知識を磨くことに決めました(私が残した知識はほとんどありません)。曇った最初のスキルはメモリ管理であることにすぐに気づきました。くそー。

私は、やるべき最善のことは、無意味なポインターの練習を書くことだと決めました。1つ目は、それぞれが可変長の4つのchar配列の配列を割り当てることでした。

そのコードの簡略化されたバージョン:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char **aStr = malloc(4*sizeof(aStr));
    int j = 0;
    int i = 0;
    while(i<sizeof(aStr))
    {
        j = 4 + 2*i;//in my code, length is determined by arguments
        aStr[i] = malloc(j*sizeof(aStr[i]));
        j--;
        strncpy(aStr[i],"RaisinRubarbCarrot"+i,j);
        aStr[i][j] = 0;//just a habbit
        j++;
        printf("ptr@:%p\n\tkey:%d\n\tval:%s\n\tlength:%d (%d)\n\n",*aStr[i],i,aStr[i],j,strlen(aStr[i]));
        i++;
    }
    free(aStr);
    return 0;
}

これは不格好で直感に反していると感じました。今日、私は私の古いネミシスを思い出しました:calloc。それから私は書いた

char **aStr = (char **)calloc(4, sizeof(char *));

そしてループ内:

aStr[i] = (char *) calloc(j,sizeof(char *));

私は次のように最後の行を書くコード例を見つけました:

aStr[i] = (char *) calloc(j,sizeof(char));//without the asterisk

質問1:違いは何ですか?

質問2:文字列の配列を割り当てる別の方法はありませんか?私が今コードを見ると、最初に4つのポインターを1つのcharポインターに割り当て、次に各ポインターに必要な実際のサイズを割り当てているように感じます。それはただ間違っていると感じます。

それからまた、私はこれらすべてについて間違っているかもしれません、その場合:壁に頭をぶつけて、あなたの時間を無駄にする前に私が読むべきまともなマニュアルの方向に私を向けてください...

4

2 に答える 2

3

char *charは2つの異なるタイプであり、データサイズが異なります。Acharは常に1バイトであるため、sizeof(char)常に1です。一方、charへのポインタは、32ビットシステムでは4バイトになります。したがってsizeof(char*)、文字列にスペースを割り当てるために使用する場合、必要以上に多くを割り当てることになります。

ループを使用して個々の文字列を割り当てるのは問題ありません。文字列の最大長を想定すると、 1つの大きなブロックを割り当てることができますが、それは不器用です。

于 2012-08-13T22:48:05.780 に答える
1
  1. poinersの配列ではなくcharの配列にメモリを割り当てようとしているため、sizeof(char *)の代わりにsizeof(char)を使用する必要があります。したがって、これは正しいバージョンです。

    aStr[i] = (char*) calloc(j, sizeof(char)); 
    //first argument number of memory
    //locations to be allocated
    //second argument, size of each location
    

    mallocに対するcallocの違い/利点は、メモリ位置も0に初期化したことです。

  2. 最初に、4つのポインターの配列をcharsに割り当てます。次に、各文字列にメモリを割り当てます(以前に割り当てられた4つのポインタのそれぞれが、これらの配列の1つを指します)

于 2012-08-13T22:52:07.080 に答える