0

最近、Cポインタで問題が発生しました。ご覧のとおり、STDINからデータを読み取るループがあります。問題は、自分が何をしたのかよくわからないことです。

このstruct_CONTAINER構造体にメモリを割り当てました。BUFFER_SIZEの長さのc文字列の配列が必要でした。私が正しく理解していれば、この配列にはBUFFER_SIZE(char *)オブジェクトが含まれています。つまり、この配列の重みは8 * BUFFER_SIZEバイト(各charポインターに対して最大8バイト)になります。したがって、たとえば、BUFFER_SIZEが値10で定義されている場合、この配列に80バイトが与えられ、構造全体のサイズはおそらく同じになります。

問題は、BUFFER_SIZEより大きい値でそのポインタを反復処理できることと、私にとって奇妙なことです。つまり、メモリはNULLではありません。そのループで、すでに割り当てられている他のメモリにアクセスしようとしている可能性があることを私は知っています。確信はないけど。誰かが親切で、私が正しいことと間違っていることを教えてくれたら。メモリ割り当てが大きすぎる可能性があります。前もって感謝します!

char *item = NULL;

if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}

memset( reading, '\0', BUFFER_SIZE );

struct struct_CONTAINER{
    char *container[BUFFER_SIZE];
};


while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    item = &shmemContainer->container[i++];
    strcpy(item, reading);
    memset( reading, '\0', BUFFER_SIZE );
}

編集:「アイテム」変数のタイプを表示するのを忘れました

4

2 に答える 2

1

構造体メンバーcontainerchar*タイプは、文字列の配列を意味します。itemあなたはその文字列のアドレスに割り当てて char**、呼び出しようとしますstrcpy(item, reading);

あなたは少なくとも次のステートメントの1つで間違ったことをしています。

 item = &shmemContainer->container[i++];
        ^   is wrong 
 strcpy(item, reading);
         ^ or this is wrong

[回答]最初のポイントはコードのエラーです演算子の優先順位
がより高い ため。コードをコンパイルすると、警告が表示されます。->&

  • 最初の式item = &shmemContainer->container[i++]; が間違っている場合は、次のように記述します。

    item = (&shmemContainer)->container[i++];

  • strcpy(item, reading); 間違っている場合は、次のように修正してください。

    strcpy(*item, reading);

そして、私があなたのwhileループから理解できるように、あなたは文字列fdinを文字列配列に読みたいと思っています、そしてあなたは次のようにすることができます:

while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

reading[r_control] = '\0'; 初めて行方不明になったときは、文字列を自分で終了しないmemset()ことを忘れないでください。read()\0

編集:各文字列にメモリを割り当てるようにしている
ので、@Digikataのコメントを検討してください。strcpy()container[]

私のおすすめ:

container[]は文字列の配列であるため、次のようにwhileループにメモリを割り当てることができます。

i = 0;
while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    shmemContainer->container[i] = malloc(strlen(reading) + 1);
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

不足している場合は、メモリ割り当てを追加しました。

于 2013-03-24T18:00:10.790 に答える
0

Cは、意図したメモリ位置を超えてインデックスを作成することを妨げません。例えば:

char astring[5] = "0123";  // there is a zero at index 4 
char* ptr = astring;       // ptr[4] == 0

printf("%c", ptr[5]);  // reads a byte beyond the end of the string array 

そこにはデータが頻繁に存在するため、コードはそれが発生しないように論理的に防ぐ必要がありますが、それを書き込む(場合によっては読み取る)と、未定義の動作が発生します。したがって、コードでは、コンテナを超えた領域がNULLではないと読み取るのは正常です。

ところで、c-stringを指すchar *型と、上記のコードの「ptr」、「astring」変数などの割り当てられたメモリ領域の違いを理解しているかどうかは、質問からは明らかではありません。サンプルコードでは、文字列にメモリが割り当てられていません。

于 2013-03-24T18:39:37.333 に答える