3

構造体データ型を定義します。

typedef struct LinkNode LinkNode;
struct LinkNode {
    char *name;
    LinkNode *next;
};

そしてそれを main() で呼び出します: Example1:

int main()
{
    LinkNode *pnode = (LinkNode *) malloc(sizeof(LinkNode));

    scanf("%s", pnode->name);
    ...
    free(pnode);
    return 0;
}

1行追加しない限り、機能しません:Example 2

int main()
{
    LinkNode *pnode = (LinkNode *) malloc(sizeof(LinkNode));
    pnode->name = (char *) malloc(sizeof(char));

    scanf("%s", pnode->name);
    ...
    free(pnode);
    return 0;
}

ただし、次のコードは機能します。Example 3

int main()
{
    LinkNode *pnode = (LinkNode *) malloc(sizeof(LinkNode));

    pnode->name = "Jim";
    ...
    free(pnode);
    return 0;
}

だから問題は何ですか?pnode にメモリーが割り当てられていますが、なぜ scanf() が機能しないのですか? 私はVS2010を使用しています。ありがとう!

4

5 に答える 5

2

を使用する場合scanf、書き込み先として割り当てられたメモリ ブロックが必要です。メモリを割り当てるnamemalloc、有効なメモリアドレスがあるため、(@billz が指摘したように) 1 バイトを割り当てるだけであっても機能します。ただし、十分なメモリを割り当てる必要があります。そうしないと、何かを上書きして、遅かれ早かれ問題が発生します。

pnode->name = (char *) malloc(sizeof(char) * <max size of input>);

name文字列リテラルをポインター( )に割り当てるとpnode->name = "Jim";、メモリ内のハードコードされた文字列のアドレスに設定されるだけです。変更しようとすると悪いことが起こるので、const ポインターを使用していない限り、絶対に変更しないでください。

要するに、nameこれは単なるポインターであり、それを使って何かを行うには、有効なものを指す必要があります。

于 2012-12-17T03:02:08.783 に答える
2

構造体にメモリを割り当てると、ノード全体のメモリのみが作成され、内部で使用されるポインタ (名前) は作成されません。したがって、明示的にメモリを割り当てる必要があります。1. pnode->name に対して malloc を実行し、メモリを割り当ててから書き込みを試みました。したがって、これらのスニペットは機能します。

于 2012-12-17T03:07:06.967 に答える
1

C++ を使用できるので、C++ の方法を提案したいと思います。私のサンプルコードとコメントを見てください

#include <string>
struct LinkNode {
    std::string name;    // let string manage dynamic memory instead of raw pointer
    LinkNode *next;
};     

int main()
{
  LinkNode *pNode = new LinkNode;  // use new instead of malloc
  std::cin >> pNode->name;         // use std::cin instead of scanf    
  delete pNode;
  return 0;
}
于 2012-12-17T06:11:30.873 に答える
1

scanf()何十年も前から存在しています。何が問題だと思いますか?あなたのコードまたはスキャン?:)。

最初の例では、オブジェクトをLinkNode *pnode = (LinkNode *) malloc(sizeof(LinkNode));割り当てますが、 . したがって、メモリの場所であるため、割り当てられるまでジャンクアドレスが含まれています。LinkNodechar *name

There are three correct ways to assign a `char*`:
1. Create dynamic memory space and then assign it to the `char *`
2. Assign it to a constant string such as "Jim" in your example
3. Assign the pointer to another pointer that has been created by either 1 or 2

そして、これはまさにあなたがしていることです。2 番目の例では、文字列データ用のスペースを作成し、それを に割り当てますpnode->name

pnode->name3番目の例では、定数文字列に割り当てます。

これが C ポインタの仕組みです。

今度はscanf(): 空白が見つかるまで入力を読み取り、それを書式設定して文字配列バッファに割り当てます。mallocしたがって、スタックで初期化された文字配列、または動的に作成された文字配列 (を使用)が必要になります。

于 2012-12-17T03:08:46.593 に答える
0

LinkNode2 つのポインターで構成されます。32 ビット アーキテクチャでは、 sizeof(LinkNode)8 バイト (ポインターごとに 4 バイト) に相当します。

構造体のメモリを取得すると、2 つのポインターに十分なスペースが得られますが、それが指すデータには別のメモリを割り当てる必要があります。したがって、あなたが望むことを行う正しい方法は、2 つmallocの s を実行することです。1 つは構造体用、もう 1 つは内部文字列バッファー用です。

次のようにして静的バッファを作成することもできます

typedef struct LinkNode LinkNode;
struct LinkNode {
    char name[256];
    LinkNode *next;
};

その場合、 にメモリを割り当てるLinkNodeと、内部バッファにも十分なメモリが得られます。

于 2012-12-17T03:09:52.773 に答える