あなたのプログラムが構文的に有効なC++ですが、ヒープアロケータにスタックオブジェクトのアドレスを渡すので、それは未定義の動作を生成します。通常、これは実行時にプログラムがクラッシュすることを意味します。
スタックとヒープは、プログラムを実行するプロセスに割り当てられた2つの異なるメモリ領域です。スタックは、引数とローカル変数を保持する関数を入力すると増加し、関数から戻ると自動的に縮小します。一方、ヒープは、要求に応じてメモリを取得できる独立したアドレス領域であり、不要になったときに明示的に解放する必要があります。
ローカル変数のアドレスがrealloc()に渡された場合、そのメモリを解放して他の場所に割り当てることができます。アドレスはヒープからではなく、realloc()がヒープ上で動作するため、これは失敗します。ほとんどの場合、realloc()はアドレスがヒープからではなく、プログラムを中止することを検出します。
これ以外にも、サンプルプログラムにはいくつかの論理エラーがあります。
char myString = NULL;
文字列ではなくcharを保持する変数を宣言します。 Cスタイルの文字列は、タイプがchar*
であり、charへのポインタです。
また、charはNULL
と割り当てられています。アドレス0は、通常は無効なポインタに割り当てられます。これは、プリプロセッサがNULL
をリテラル0
に置き換えたためにコンパイルされます。実際には、ゼロバイトをcharに格納します。これは、通常はCスタイルの文字列の終端文字です。
上記のように、スタックオブジェクトのアドレスをヒープアロケータに渡すため、これは不正です。この問題は、2番目のコード例に残ります。
また、戻り値を破棄します。 realloc()
は、新しいメモリが割り当てられたアドレスを返します。以前と同じアドレスではない可能性があります。それはNULLであるかもしれません、それはrealloc()
のそれがメモリから去ったことを伝える方法です。
strncpy((char *)&myString, "test", 5);
これは正しいですが、キャストは冗長です。完全に)(reallocのを避けた方がよい、C++では
#include <stdlib.h>
#include <string.h>
int main()
{
/* allocate space for, say, one character + terminator */
char* myString = (char*) malloc(2);
/* some code using myString omitted */
/* get more space */
myString = (char*) realloc(myString, 5);
/* write to the string */
strncpy(myString, "test", 5);
/* free the memory */
free(myString);
return 0;
}
:ここ
は、あなたのプログラムのより適切なバージョンです。たとえば、次のようなものを使用できます。
#include <string>
int main()
{
std::string myString;
/* some code using myString */
myString = "test";
return 0;
}
はい、第2の亜種は「決してそうしない」部門のものです。 – sharptooth
具体的には、malloc()、calloc()、またはrealloc()によって与えられなかった値を決してrealloc()するべきではありません。 –