我定义了一个struct数据类型:
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;
}
它不起作用,除非添加一行: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。 谢谢!
答案 0 :(得分:2)
使用scanf
时,需要一个已分配的内存块才能写入。当您为name
分配malloc
的内存时,即使您只是分配一个字节(如@billz指出),因为您现在拥有有效的内存地址。你必须分配足够的内存,否则你将会覆盖一些东西并迟早会引起麻烦。
pnode->name = (char *) malloc(sizeof(char) * <max size of input>);
将字符串文字指定给指针name
(pnode->name = "Jim";
)时,只需将其设置为内存中硬编码字符串的地址即可。如果你试图修改它会发生坏事,所以除非你使用const指针,否则永远不要这样做。
底线,name
只是一个指针,对它做任何事情,你需要它指向有效的东西。
答案 1 :(得分:2)
为结构分配内存时,它只为整个节点创建内存,但不为其中使用的指针(名称)创建内存。所以你必须明确地为它分配内存。 1.你为pnode-&gt;名字做了一个malloc,分配了内存,然后尝试写入它 2. pnode-&gt; name =“some string”,通过执行此操作,您将分配内存并将值存储在其中。 因此,这些片段有效。
答案 2 :(得分:1)
scanf()
已经存在了几十年。您认为这个问题是什么?你的代码还是scanf? :)
在第一个示例中,LinkNode *pnode = (LinkNode *) malloc(sizeof(LinkNode));
分配LinkNode
个对象,但不初始化char *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
这正是你所做的。在第二个示例中,为字符串数据创建空间,然后将其分配给pnode->name
。
在第3个示例中,您将pnode->name
分配给常量字符串。
这就是C指针的工作方式。
现在来到scanf()
:它将读取输入,直到遇到空格,并将其格式化为字符数组缓冲区。因此,您将需要一个堆栈初始化的字符数组,或动态创建的字符数组(使用malloc
)
答案 3 :(得分: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;
}
答案 4 :(得分:0)
LinkNode
由两个指针组成。在32位架构中,sizeof(LinkNode)
等于8个字节(每个指针4个字节)。
当您获得结构的内存时,您将获得足够的空间用于两个指针,但它指向的任何数据都必须分配其单独的内存。因此,做你想做的事的正确方法是做两个malloc
。一个用于struct,另一个用于内部字符串缓冲区。
您也可以通过
获得静态缓冲区typedef struct LinkNode LinkNode;
struct LinkNode {
char name[256];
LinkNode *next;
};
在这种情况下,为LinkNode
分配内存也会为内部缓冲区提供足够的内存。