1

現在、C++ の C 側を学習しようとしています。

mallocの char 配列のメモリのチャンクを取得しようとして256、それを割り当てましたchar* "Hello World!"が、オブジェクトを解放しようとするとエラーが発生します。

誰でも私にエラーを説明してください。

#include <exception>
#include <stdexcept>
#include <iostream>

int main()
{
    void* charVoidPointer = malloc( sizeof(char) * 256 ) ;
    charVoidPointer = "Hello World";

    std::cout << (char *)charVoidPointer;
    free (charVoidPointer);
}
4

4 に答える 4

2
void* charVoidPointer = malloc( sizeof(char) * 256 ) ;

charVoidPointer(ちなみに奇妙な名前-文字が必要な場合char *は、mallocから返されたポインターを使用してキャストします)は256文字のブロックを指します。このブロックは初期化されていないため、できることはほとんどすべてに何らかの値を設定するか、何かをコピーすることだけです。

charVoidPointer = "Hello World";

代わりcharVoidPointerに、静的に割り当てられた文字配列を指すようになり、malloc によって返されたアドレスが失われました。元に戻す方法がないため、これはリソース リークです。


コードは次のようになります。

char *charPointer = (char *)malloc(256);
strcpy(charPointer, "Hello World");

文字配列を割り当てられたブロックにコピーします。または、もっと簡潔に言うと、

char *charPointer = strdup("Hello World");

これにより、適切なサイズのブロックが割り当てられ、文字列がコピーされます。ブロックはfree.

于 2012-07-14T16:22:46.550 に答える
2

「Hello World」は、コンパイラによって静的に割り当てられます。これはプログラムの一部であり、プログラムによってアドレス可能な場所に存在します。アドレス 12 と呼びます。

charVoidPointer は、最初は malloc によって割り当てられた場所を指しています。アドレス 98 と呼びます。

charVoidPointer = "Hello ..." は、charVoidPointer がプログラム内のデータを指すようにします。以前に charVoidPointer に含まれていたアドレス 98 を追跡できなくなります。

また、malloc によって割り当てられていないメモリを解放することはできません。

私が意味することをより文字通りに示すには:

void* charVoidPointer = malloc(sizeof(char) * 256);
printf("the address of the memory allocated for us: %p\n", charVoidPointer);
charVoidPointer = "Hello World";
printf("no longer the address allocated for us; free will fail: %p\n",
       charVoidPointer);

あなたが意味したのは:

strcpy(charVoidPointer, "Hello World");

編集:他のタイプのメモリのアドレス指定の例

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

int main()
{
  // an array of 10 int
  int *p = (int*)malloc(sizeof(int) * 10);

  // setting element 0 using memcpy (works for everything)
  int src = 2;
  memcpy(p+0, &src, sizeof(int));

  // setting element 1 using array subscripts.  correctly adjusts for
  // size of element BECAUSE p is an int*.  We would have to consider
  // the size of the underlying data if it were a void*.
  p[1] = 3;

  // again, the +1 math works because we've given the compiler 
  // information about the underlying type.  void* wouldn't have
  // the correct information and the p+1 wouldn't yield the result
  // you expect.
  printf("%d, %d\n", p[0], *(p+1));

  free (p);
}

実験; 型を int から long、または double、または何らかの複合型に変更します。

于 2012-07-14T16:23:28.843 に答える
1

strcpy(charVoidPointer, "Hello World");あなたの例では、ポインターを再割り当てするために使用します。

于 2012-07-14T16:18:20.297 に答える
1

文字列リテラル「Hello World」のアドレスにポインタを割り当てているため、malloc したメモリ ブロックがリークしています。

使用する必要があります

strcpy(charVoidPointer, "Hello World");

代入演算子の代わりに。

さらに良いのは、strncpy(charVoidPointer, "Hello World", 255);割り当てた配列のオーバーフローを避けるために使用することです。

于 2012-07-14T16:18:43.613 に答える