将堆 space 分配给 C 中自定义数据类型的一个元素
Allocating heap space to one element of custom data type in C
我有以下数据类型:
typedef struct {
int num;
char *str;
} NumStr;
和变量 x:
NumStr *x;
如何为 str 指针分配堆 space?我试过了
x->str = (char*)malloc(sizeof(char*));
但它不起作用。
我是 C 的新手,所以如果我遗漏了一些明显的东西,我深表歉意。提前致谢。
像 NumStr*
这样的指针指向内存中的某处 - 因此您需要在分配给 x->str
之前分配 x
:
NumStr* x = malloc(sizeof(*x));
.
请注意,您已经完成 no need to cast to (char*)
- 不要忘记按特定顺序 free(x->str);
然后 free(x);
。
你可以简单地做
NumStr x;
x.int = 3;//for example
x.str = malloc(5*sizeof(char));
如果以后需要指向 x
的指针(几乎等同于代码中的 x
),只需使用 &x
.
我的代码说明:
x 会自动分配到堆栈上,就像 int 一样(如 int x; x = 0;
)。之后您可以自由初始化它(如我上面的示例)。 NumStr *x
声明分配 NumStr *
类型的变量,指针,您通常使用 malloc 初始化(如丹尼尔的回答),然后才初始化分配的内存。
(一如既往地使用 -allocs)你需要 free
稍后你自己指向的内存。
再澄清一件事:x->str = (char*)malloc(sizeof(char*));
应更正为 x->str = malloc(sizeof(char));
,可选 x->str = malloc(5*sizeof(char))
或其他内容。
就您的实际问题而言:
How can I allocate heap space for the str pointer?
您所做的 (x->str = (char*)malloc(sizeof(char*));
) 可能不是您想要的。 sizeof(char*)
很可能是 4 或 8,具体取决于您的系统,但更重要的是与 x->str
将指向的 char
对象无关。分配动态内存时,一般范例是从您分配给的左值为类型“向上一级”分配 space,作为 sizeof
该类型和 [ 的数量的组合=87=]想要的。也就是说,对于某些类型 T
,您希望按以下方式分配 space:
// pseudo code
T* myPointerToT = malloc(sizeof(T) * numberOfTObjectsIWant);
这里,myPointerToT
是一个T指针类型(T*
)。 “向上一级”是一种类型 T
,因此这就是您要提供给 sizeof
的内容。 T*
类型应该 指向 到 T
个对象,因此您必须为所需的 T
个对象分配足够的大小。
还有一件事,而不是在 sizeof(T)
中使用 T
,首选语法是使用取消引用的变量名。在上面的示例中,这将是 *myPointerToT
,将行更改为:
T* myPointerToT = malloc(sizeof(*myPointerToT) * numberOfTObjectsIWant);
此后维护较少的原因。假设 T
是 char
,一段时间后,它变为 int
。我们现在必须在两个地方更改 T
:
char* myPointerToT = malloc(sizeof(char) * numberOfTObjectsIWant);
更改为
int* myPointerToT = malloc(sizeof(int) * numberOfTObjectsIWant);
而如果我们从
开始
char* myPointerToT = malloc(sizeof(*myPointerToT) * numberOfTObjectsIWant);
我们现在只需要改变一个地方的T:
int* myPointerToT = malloc(sizeof(*myPointerToT) * numberOfTObjectsIWant);
注意,sizeof
是一个编译时运算符,所以 *myPointerToT
并不是真正取消引用任何东西;预处理器可以查看并确定类型,这是 sizeof
需要的。
在你的例子中,x->str
是一个 char*
类型,所以你想为至少一个 char
对象分配 space。
// as stated in another answer, no need to cast malloc return value
x->str = malloc(sizeof(char));
// or
x->str = malloc(sizeof(*(x->str)));
实际上,为单个 char
分配 space 是愚蠢的,正如您的变量名所示,这意味着是一个字符串,因此您需要多个 char
s:
x->str = malloc(sizeof(char) * numOfCharsIWant);
另外,C标准定义sizeof(char)
为1,所以这个也可以省略:
x->str = malloc(numOfCharsIWant);
最后,只有在“必须”时才应动态分配内存,实际上通常归结为:
- 直到运行时您才知道需要多少内存
- 您需要“大量”内存。 “很多”的含义取决于您的系统,但根据我的经验,桌面上每个执行线程的默认堆栈大小 linux 是 8MB,这对于日常操作来说足够 space。
如果您大致了解最大字符串大小,则可以绕过动态内存分配,同时执行以下操作:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LENGTH 30 // "small enough"
typedef struct {
int num;
char str[MAX_STR_LENGTH];
} NumStr;
int main(void)
{
// a single object, keep it in automatic storage
NumStr x;
x.num = 3;
strcpy(x.str, "hello")
printf("%d: %s\n", x.num, x.str);
// no need to clean up dynamically allocated memory, since there is none
return 0;
}
你用过
x->str = (char*)malloc(sizeof(char*));
但是 sizeof
运算符会给你指针类型本身的大小(这不是你想要的,因为指针已经在结构中分配 space )。如果你想为一个字符串分配 space,比方说,50 个字符,你应该使用
x->str = malloc(50); /* don't use a cast to convert the pointer type,
* malloc already solves that, giving you a
* compatible pointer type. */
并且您应该将其用作指向 50 个字符数组 (char [50]
) 的指针。
我有以下数据类型:
typedef struct {
int num;
char *str;
} NumStr;
和变量 x:
NumStr *x;
如何为 str 指针分配堆 space?我试过了
x->str = (char*)malloc(sizeof(char*));
但它不起作用。
我是 C 的新手,所以如果我遗漏了一些明显的东西,我深表歉意。提前致谢。
像 NumStr*
这样的指针指向内存中的某处 - 因此您需要在分配给 x->str
之前分配 x
:
NumStr* x = malloc(sizeof(*x));
.
请注意,您已经完成 no need to cast to (char*)
- 不要忘记按特定顺序 free(x->str);
然后 free(x);
。
你可以简单地做
NumStr x;
x.int = 3;//for example
x.str = malloc(5*sizeof(char));
如果以后需要指向 x
的指针(几乎等同于代码中的 x
),只需使用 &x
.
我的代码说明:
x 会自动分配到堆栈上,就像 int 一样(如 int x; x = 0;
)。之后您可以自由初始化它(如我上面的示例)。 NumStr *x
声明分配 NumStr *
类型的变量,指针,您通常使用 malloc 初始化(如丹尼尔的回答),然后才初始化分配的内存。
(一如既往地使用 -allocs)你需要 free
稍后你自己指向的内存。
再澄清一件事:x->str = (char*)malloc(sizeof(char*));
应更正为 x->str = malloc(sizeof(char));
,可选 x->str = malloc(5*sizeof(char))
或其他内容。
就您的实际问题而言:
How can I allocate heap space for the str pointer?
您所做的 (x->str = (char*)malloc(sizeof(char*));
) 可能不是您想要的。 sizeof(char*)
很可能是 4 或 8,具体取决于您的系统,但更重要的是与 x->str
将指向的 char
对象无关。分配动态内存时,一般范例是从您分配给的左值为类型“向上一级”分配 space,作为 sizeof
该类型和 [ 的数量的组合=87=]想要的。也就是说,对于某些类型 T
,您希望按以下方式分配 space:
// pseudo code
T* myPointerToT = malloc(sizeof(T) * numberOfTObjectsIWant);
这里,myPointerToT
是一个T指针类型(T*
)。 “向上一级”是一种类型 T
,因此这就是您要提供给 sizeof
的内容。 T*
类型应该 指向 到 T
个对象,因此您必须为所需的 T
个对象分配足够的大小。
还有一件事,而不是在 sizeof(T)
中使用 T
,首选语法是使用取消引用的变量名。在上面的示例中,这将是 *myPointerToT
,将行更改为:
T* myPointerToT = malloc(sizeof(*myPointerToT) * numberOfTObjectsIWant);
此后维护较少的原因。假设 T
是 char
,一段时间后,它变为 int
。我们现在必须在两个地方更改 T
:
char* myPointerToT = malloc(sizeof(char) * numberOfTObjectsIWant);
更改为
int* myPointerToT = malloc(sizeof(int) * numberOfTObjectsIWant);
而如果我们从
开始char* myPointerToT = malloc(sizeof(*myPointerToT) * numberOfTObjectsIWant);
我们现在只需要改变一个地方的T:
int* myPointerToT = malloc(sizeof(*myPointerToT) * numberOfTObjectsIWant);
注意,sizeof
是一个编译时运算符,所以 *myPointerToT
并不是真正取消引用任何东西;预处理器可以查看并确定类型,这是 sizeof
需要的。
在你的例子中,x->str
是一个 char*
类型,所以你想为至少一个 char
对象分配 space。
// as stated in another answer, no need to cast malloc return value
x->str = malloc(sizeof(char));
// or
x->str = malloc(sizeof(*(x->str)));
实际上,为单个 char
分配 space 是愚蠢的,正如您的变量名所示,这意味着是一个字符串,因此您需要多个 char
s:
x->str = malloc(sizeof(char) * numOfCharsIWant);
另外,C标准定义sizeof(char)
为1,所以这个也可以省略:
x->str = malloc(numOfCharsIWant);
最后,只有在“必须”时才应动态分配内存,实际上通常归结为:
- 直到运行时您才知道需要多少内存
- 您需要“大量”内存。 “很多”的含义取决于您的系统,但根据我的经验,桌面上每个执行线程的默认堆栈大小 linux 是 8MB,这对于日常操作来说足够 space。
如果您大致了解最大字符串大小,则可以绕过动态内存分配,同时执行以下操作:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LENGTH 30 // "small enough"
typedef struct {
int num;
char str[MAX_STR_LENGTH];
} NumStr;
int main(void)
{
// a single object, keep it in automatic storage
NumStr x;
x.num = 3;
strcpy(x.str, "hello")
printf("%d: %s\n", x.num, x.str);
// no need to clean up dynamically allocated memory, since there is none
return 0;
}
你用过
x->str = (char*)malloc(sizeof(char*));
但是 sizeof
运算符会给你指针类型本身的大小(这不是你想要的,因为指针已经在结构中分配 space )。如果你想为一个字符串分配 space,比方说,50 个字符,你应该使用
x->str = malloc(50); /* don't use a cast to convert the pointer type,
* malloc already solves that, giving you a
* compatible pointer type. */
并且您应该将其用作指向 50 个字符数组 (char [50]
) 的指针。