2017-02-13 11 views
-1

malloc()について私が理解していることによると、実行時に動的にメモリを割り当てることができます。以下は、私は私の質問は、私がmalloc()機能でメモリの2つのバイトを割り当てるためのシステムを求めていますされmallocは割り当てられたデータバイトよりも多くのバイト数をとることができます

#include<conio.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
void main() { 
    char *description; 
    clrscr(); 
    description = malloc(2*sizeof(char)); 
    strcpy(description,"Hello there!"); 
    printf("%s",description); 
    free(description); 
    printf("%s",description); 
    getch(); 
} 

に探していたコードです。だから私は文字列"Hello there!"を入力して同じを印刷しようとすると、私は出力として文字列の最初の2文字だけを取得する必要がありますが、私はstrcpy()出力で関数を与えている全体の文字列を取得しています。

free()を使用した後も、descriptionを再度印刷しようとすると、何も出力されないはずですが、同じ文字列を再度取得しています。これがどのように機能するかを知ることができます。私はturbo C++コンパイラを使用しています。

+7

あなたは足で自分を撃っています。これは、C言語が足で自分を撃つことを可能にする伝統とデザインの決定です。 – user3528438

+3

Cのようなシステム言語では、自分自身を足で撃たなければなりません。解決策はそれをしないことです。 – DeiDei

+4

上記のコメントをもっと鈍くするには、Cはあなたが何をしているのか知る必要があります。 – StoryTeller

答えて

2

Mallocは2バイトを割り当てます。これは、開始点(mallocから返されたもの)から2バイトを得ることを意味します。 strcpyは、文字列 "hello there!"のすべてのバイトをコピーします。説明のアドレスから開始します。これは割り振りを気にせず、単にバイトをコピーします。 printfの%sは、printfにヌル終了文字列を探すよう指示します。

free()は、バイトが他の目的に再び使用できることをメモリマネージャに伝えるために使用されます。すでに存在するデータは消去されません。

@Michael Foukarakisが指摘するように、未割り当てメモリにバイトを書き込むと、未定義の動作が発生する可能性があります。文の間に割り当てられていないメモリに何か他のものが書かれていたら、物事は壊れてしまいます。

+0

ありがとう、パトリック!説明から割り当てを解放するためにfree()関数を使用した後でも、データをどのように印刷することができるか分かります。 –

+0

free()は、バイトが他の目的のために再び使用できることをメモリマネージャに伝えるために使用されます。既に存在するデータは消去されません –

+0

ありがとうございます。それは私の質問を説明しています:) –

1

あなたがより多くのデータを入れたら、マーリーの大きさが爆発的になります。

あなたの悪い行為について警告することはありませんが、いつでもメモリ障害が発生する可能性があります。

1
description = malloc(2*sizeof(char)); 

2バイトのストレージを要求しています。成功の場合、それはすべてのメモリですdescriptionあなたが安全に使用できることを指し示します。

strcpy(description,"Hello there!"); 

あなたはmallocに割り当てられたメモリの終わりを過ぎて書いている(証拠:「!こんにちは」以上の2の長さを有する)、したがって、あなたのプログラムは、未定義の動作を呼び出します。

printf("%s",description); 
free(description); 
printf("%s",description); 

上記の3行は、未定義の動作を引き起こすプログラムでは意味を持ちません。彼らからの期待は根拠がなく、間違っています。

descriptionが指す文字列をfree(description);の後に印刷しようとすると、未定義の動作も発生します。

+0

マイケルをよく説明してくれてありがとう。私は実際に足で自分自身を撃っていた。 –

4

malloc()ファンクションは、少なくとも必要なメモリ容量を割り当てます。しかし、malloc()が提供するメモリ量は、ここでの中心的な問題ではありません。

Cのプログラミング言語は、速度と効率を考慮して設計されているため、他の言語で行われている多くのチェックが行われていません。だからあなたは何か間違ったことをするプログラムを書くことができ、それはまだいくつかの状況下で動作し、他の状況では動作しません。

Cでは、ポインタはメモリ位置のアドレスです。 Cは、アドレスが有効なアドレスかどうかをチェックしません。 Cは、使用しようとしているメモリの量が正しいメモリ量であることを確認しません。

ここには、プログラムの注釈付きバージョンがあります。

#include<conio.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
void main() { 
    char *description; // create a variable that will contain the address of a character 
    clrscr(); 
    // allocate an array of characters. the number of characters is 2 so this 
    // will allocate a minimum size memory area that will hold 2 characters. 
    // malloc() may round up the size or it may not but all you can count on 
    // is 2 characters in size. 
    description = malloc(2*sizeof(char)); 
    // copy a constant string to the memory location pointed to by the variable 
    // description. the strcpy() function does not check on the limits of the 
    // memory. after the malloc() is done there is no size information available 
    // to strcpy() or any other of the C runtime library functions in the C Standard Library 
    // this is copying 11 characters plus the end of string for a total of 12 characters 
    // so to be correct the memory area pointed to by description should be at least 
    // 12 characters however we know from the malloc() above it is guaranteed to 
    // be only 2 characters so we are going past the memory area with this strcpy(). 
    strcpy(description,"Hello there!"); 
    // however we get lucky and it works anyway. 
    printf("%s",description); 
    // tell the memory allocation library that you are done with the memory and it 
    // can be used for something else now. the pointer will probably still be good 
    // for a while because the memory allocation, which gets its memory from the 
    // operating system, does not normally give any freed memory back to the OS. 
    // instead it normally just keeps it until the application terminates. 
    // as long as this freed memory is not used for something else, more than 
    // likely whatever you put there will remain there as is. however the moment 
    // the memory is given to something else, the values will change. 
    free(description); 
    printf("%s",description); 
    getch(); 
} 

あなたが代わりにmalloc()を使用してのスタック上の変数を使用していますあなたの変形である以下のサンプルプログラムをしようと何が起こっているかのようなアイデアを得ることができます。

Visual Studio 2013を使用してデバッグモードで実行すると、アプリケーションの終了時にメモリが上書きされるという警告が表示されます。私がリリースビルドを行い、それを実行すると、エラーはなく、次の出力が得られます。ご覧のとおり、strcpy()関数は、隣接するメモリを上書きする文字をコピーしました。 Visual Studio 2013コンパイラのように、ダブルワード境界にメモリを配置すると、隣接するメモリ領域に文字列の最後の数文字しか表示されないように見えます。 Visual Studioは変数array2[]をパディングし、割り当てられた次の変数がダブルワード境界になるようにしました。

Before 
    array1 
    array2 
    array3 
description Hello there! 

After 
    array1 
    array2 Hello there! 
    array3 ere! 

私たちは、下記を上記のプログラムを変更する場合:

#include<conio.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
void main() { 
    char array1[12] = { 0 }; 
    char array2[2] = { 0 }; 
    char array3[12] = { 0 }; 
    char *description; 
    int *values; 
    printf("Before\n array1 %s\n", array1); 
    printf(" array2 %s\n", array2); 
    printf(" array3 %s\n", array3); 

    description = &array2[0]; 
    strcpy(description, "Hello there!"); 
    printf("description %s\n", description); 

    printf("\nAfter\n array1 %s\n", array1); 
    printf(" array2 %s\n", array2); 
    printf(" array3 %s\n", array3); 

    description = malloc(8 * sizeof(char)); 
    strcpy(description, "this"); 
    printf("\n\nMalloc\n first description %p %s\n", description, description); 
    free(description); 

    values = malloc(1 * sizeof(int)); 
    *values = 0; 
    printf(" pointer %p and value %d\n", values, *values); 
    printf(" second description %p %s\n", description, description); 

} 

をその後、我々は次の出力を取得します。この場合、malloc()のにはintの同じメモリ領域が割り当てられました。したがって、intを修正したときに、descriptionの領域も変更されました。malloc()は、次の割り当て領域を再利用したためです。

Before 
    array1 
    array2 
    array3 
description Hello there! 

After 
    array1 
    array2 Hello there! 
    array3 ere! 


Malloc 
    first description 00944B28 this 
    pointer 00944B28 and value 0 
    second description 00944B28 

malloc()free()を使用した場合、リソースの所有権原理

この例では、2つのルールを示しています。

malloc()を割り当てると、必要なメモリ容量を超えることはありません。もっと必要な場合はrealloc()の機能を見てください。

free()を使用してメモリ領域を解放したら、そのポインタ値を再度使用しないでください。一度解放されると、メモリ領域を所有しなくなります。

malloc()を使用すると、あなたが要求したメモリだけがメモリの所有者になります。 free()を使用するときは、メモリの所有権を放棄し、もはやそれを所有していないため、使用しないでください。

関連する問題