1

次のコードを検討してください:

#include "stdafx.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

struct Person {
    char *name;
    int age;
    int height;
    int weight;
};

struct Person *Person_create(char *name, int age, int height, int weight)
{
    struct Person *who = (struct Person*) malloc(sizeof(struct Person));
    assert(who != NULL);

    who->name = strdup(name);
    who->age = age;
    who->height = height;
    who->weight = weight;

    return who;
}

気になるラインは

struct Person *who = (struct Person*) malloc(sizeof(struct Person));

malloc() の使用法についてインターネットで少し検索しました。それらの約半分はキャストで書かれており、残りはそうではありません。vs2010 では、(struct Person*)キャストせずにエラーが発生します。

1>c:\users\juhyunlove\documents\visual studio 2010\projects\learnc\struct\struct\struct.cpp(19): error C2440: 'initializing' : cannot convert from 'void *' to 'Person *'
1>          Conversion from 'void*' to pointer to non-'void' requires an explicit cast

それでは、ポインタを作成してそれにメモリを割り当てる適切な方法は何でしょうか?

4

2 に答える 2

14

C++ コンパイラを使用しているためです。

C++ ではキャストmalloc(型が でないと仮定) が必要です。void *C では必須ではなく、キャストしないことをお勧めしmallocます。

void *C では、代入中に からすべてのオブジェクト ポインター型への暗黙的な変換があります。

void *p = NULL;
int *q = p;  // valid in C, invalid in C++
于 2012-12-21T17:35:55.580 に答える
1

ファイルの名前を struct.cpp から struct.c に変更すると、コンパイラは、C++ コンパイラが行うべきことを行うのではなく、C コンパイラが行うべきことを行います (上記で説明したように)。Visual Studio には、C と C++ の両方を実行できるコンパイラが付属しているため、ファイルを作成するときにファイルに正しい名前を付けるだけです。

Visual Studio 内のファイルの名前を変更するだけで十分かどうか、または struct.c という名前の新しいファイルを追加する必要があるかどうかはわかりません。既存のファイルからコンテンツをコピーしてから、元の struct.cpp を削除します。後者は間違いなく機能します。

于 2012-12-21T20:27:40.990 に答える