1

なぜ私はこのコードを実行すると:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    size_t size = 4;
    char *str = malloc(size);
    str = "hello";
    printf("malloc %s: %d\n", str, size);
    printf("strlen %s: %d\n", str, strlen(str));
    printf("sizeof %s: %d\n", str, sizeof("hello"));
    return 0;
}

以下を取得します。

malloc hello: 4
strlen hello: 5
sizeof hello: 6

基本的に、4 バイトだけを割り当てると、6 バイトのサイズの 5 文字の文字列を格納できる理由を知る必要があります。

4

4 に答える 4

1

あなたの行str = "hello"では、 が作成されたメモリ内のスポットを指すようにポインターを再割り当てしています"hello"。ここで行っているのはmalloc、要求されたヒープ スペースへの参照がなくなったため、 で小さなメモリ リークが発生したことです。

于 2013-07-04T19:18:54.113 に答える
0

この行str = "hello";は、ポインターが別の場所を指すように設定します。(実行しようとすると、ポインターのサイズであるsizeof(str)値になります。)4

strlen(str)ヌル文字なしで文字列の長さを生成するため、5.

sizeof("hello")は、格納に必要なメモリを計算する"hello"ため、null 文字も考慮されます。そのため、出力は6. したがって、基本的に文字列には6文字があります。

于 2013-07-04T19:21:10.177 に答える
0

str = "hello"ポインタを再割り当てするだけです。割り当てたばかりのメモリには何も格納されません。メモリ リークが発生しました。

文字列の内容自体をコピーするには、 を使用する必要がありますstrncpy()

于 2013-07-04T19:18:37.797 に答える
0

Q1. 文字列バッファで異なるサイズを取得するのはなぜですか?

3 つの出力:

  1. size_tあなたのシステムでは4バイトです。これはsizeof(size)4 の理由ですが、割り当てのためではありませんsize = 4。もちろん、printf サイズの値も 4 です。
  2. 次に、5 文字で構成されるstrlen(str)string の長さを示します。"hello"(文字列の長さにヌル文字は含まれません\0)。
  3. C の文字列はchar[N](配列) 型です。3 番目の pritnf のsizeof("hello")値は 6"hello"文字列が 6 文字の長さの配列であるためです (文字列の終端は\0nul を含み、hello のタイプは ですchar[6])。

    メモリ"hello"文字列には、以下の図のように格納されます。

     str          23   24   25   26   27   28
    +----+      +----+----+----+----+----+----+
    | 23 |      | h  | e  |  l | l  | o  | \0 |    
    +----+      +----+----+----+----+----+----+
    
    Address of hello string is first address = 23  
    str: is pointer, used to store address of hello string
    

    割り当てstr = "hello";は、基本的に、上の図に示したように、文字列 hello のアドレスをポインター変数に格納しますstr

Q2. 4 バイトだけを割り当てた場合、6 バイトのサイズの 5 文字の文字列を格納できるのはなぜですか

実際には、「hello」文字列を動的に割り当てられたスペースにコピーしていません。最初 strに含まれていたのは、 によって返されたアドレスmalloc()です。しかし、代入文のためstr = "hello";、割り当てられたメモリのメモリアドレスを代入文の定数文字列リテラル「hello」で上書きしました。

これを理解するために、次の例を実行できます。

#include<stdio.h>
int main(){
 size_t size = 6;
 char *str = malloc(size);
 printf("\n malloc str: %p", str);
 str = "hello"; 
 printf("\n hello str: %p", str);
 return 1;
}

出力:

 malloc str: 0x804a078
 hello str: 0x8048609  // allocated address lost

Codepade リンク
(補足: free() を使用して明示的に割り当てを解除するときに必要になるため、動的に (明示的に) 割り当てられたメモリのアドレスを失うことはありません。 )

割り当てられたスペースにコピーする場合は、(1) 各メモリ位置にアクセス/インデックス付けして割り当てるか、(2) ライブラリ関数を使用して割り当てることができますstrcpy()

たとえば、試してみてください:

       str[0] = 'a';
       str[1] = 'b';
       str[2] = 'c';
       str[3] = '\0';  // nul termination is important 
    or 
       strcpy(str, "abc");  // strcpy add nul itself

ただし、完全な文字列を保持するのに十分なスペースが割り当てられていない"hello"ため、文字列をコピーできません。これを行うと、実行時に C/C++ で未定義の動作であるバッファ オーバーランの問題が発生します。str

于 2013-07-04T19:31:18.510 に答える