为c中自定义数据类型的一个元素分配堆空间



我有以下数据类型:

typedef struct {
int num;
char *str;
} NumStr;

和变量x:

NumStr *x;

如何为str指针分配堆空间?我试着

x->str = (char*)malloc(sizeof(char*));

但是它不工作。

我对C很陌生,所以如果我错过了一些明显的东西,我很抱歉。提前谢谢。

NumStr*这样的指针指向内存中的某个地方-因此您需要在分配x->str之前分配x:

NumStr* x = malloc(sizeof(*x));.


请注意,没有必要像您所做的那样强制转换为(char*)-并且不要忘记按特定顺序强制转换为free(x->str);free(x);

至于你的实际问题:

我如何为str指针分配堆空间?

你所做的(x->str = (char*)malloc(sizeof(char*));)可能不是你想要的。根据您的系统,sizeof(char*)很可能是4或8,但更重要的是,它与x->str指向的char对象无关。在分配动态内存时,一般范例是为"上一级"类型分配空间。从您分配给的左值,作为sizeof类型和所需空间量的组合。也就是说,对于某些类型T,您希望以以下方式分配空间:

// 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);

这样做的原因是更少的维护。假设Tchar,过了一段时间,它变成了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->strchar*类型,因此您希望至少为单个char对象分配空间。

// 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分配空间是愚蠢的,正如您的变量名所表明的,这意味着是一个字符串,因此您将需要多个chars:

x->str = malloc(sizeof(char) * numOfCharsIWant);

此外,C标准将sizeof(char)定义为1,因此也可以省略:

x->str = malloc(numOfCharsIWant);

最后,你应该只动态分配内存,如果你有To,在实践中通常可以归结为:

  1. 你不知道你需要多少内存,直到运行
  2. 你需要"很多"的内存。什么"很多"?方法取决于您的系统,但根据我的经验,桌面linux上每个执行线程的默认堆栈大小是8MB,这对于通常的操作来说是足够的空间。

如果你知道你的最大字符串大小是多少,你可以绕过动态内存分配,像下面这样做:

#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: %sn", x.num, x.str);
// no need to clean up dynamically allocated memory, since there is none
return 0;
}

你可以直接做

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初始化(如Daniel的回答),然后才初始化分配的内存。

(和使用-allocs时一样)您需要稍后自己对它所指向的内存进行free

再澄清一件事:x->str = (char*)malloc(sizeof(char*));应该更正为x->str = malloc(sizeof(char));,可选x->str = malloc(5*sizeof(char))或其他。

你使用了

x->str = (char*)malloc(sizeof(char*));

,但是sizeof操作符会给你指针类型本身的大小(这不是你想要的,因为指针已经在结构体中分配了空间)。如果你想为一个字符串分配空间,比如说,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])的指针来使用。

相关内容

  • 没有找到相关文章

最新更新