简体   繁体   English

在C中分配内存混淆

[英]Allocating memory confusion in C

I've done alot of looking around, but still can't get my head around it, lets say I have struct: 我已经做了很多环顾四周,但仍然无法理解它,让我说我有结构:

struct some_struct {
    int x;
    int y;
    char *some_string;
};

Lets say we have the above struct, how would you allocate some memory for the above struct? 可以说我们有上面的结构,你会如何为上面的结构分配一些内存? One can simply do: 人们可以简单地做到:

struct some_struct *test_struct;
test_struct = malloc(sizeof(struct some_struct));

But is this enough? 但这够了吗? Don't you need to allocate some memory for some_string ? 你不需要为some_string分配一些内存吗? Or if the struct contains more pointers, do you not need to allocate memory for them as well? 或者如果结构包含更多指针,您是否也不需要为它们分配内存?

Edit : One more thing... assuming my struct some_struct already has data in it eg 编辑 :还有一件事......假设我的结构some_struct已经有数据,例如

struct some_struct *test_struct = malloc(sizeof(some_string);
test_struct->x = 2;
test_struct->y = 3;
test_struct->some_string = "sadlfkajsdflk";

Will the following code suffice in freeing allocated memory? 以下代码是否足以释放分配的内存?

free(test_struct);

or do I have to go in and free the char* some_string as well? 或者我是否必须进入并释放char * some_string?

Thanks 谢谢

Calling malloc(sizeof(struct some_struct)); 调用malloc(sizeof(struct some_struct)); gives you memory for your struct, which includes space for two integer fields and a pointer field. 为您的结构提供内存,包括两个整数字段和指针字段的空间。

The pointer field however cannot be used until it points to a valid location in memory. 但是,指针字段在指向内存中的有效位置之前不能使用。 To do this, you need to point it to a valid memory location, by eg allocating memory for it with malloc or pointing it to a pre-existing valid memory location: 为此,您需要将其指向有效的内存位置,例如通过malloc为其分配内存或将其指向预先存在的有效内存位置:

eg: 例如:

test_struct->some_string = malloc(100); // Allocate 100 bytes for the string

After running these two lines of code: 运行这两行代码后:

struct some_struct *test_struct;
test_struct = malloc(sizeof(struct some_struct));

You've done enough to start working with test_struct . 您已经做了足够的工作来开始使用test_struct A pointer's value is just a memory address so the malloc allocates enough for two int s and one char* . 指针的值只是一个内存地址,因此malloc为两个int和一个char*分配足够的值。 If you'd like to point test_struct->some_string at an already existing char* you may do so: 如果您想将test_struct->some_string指向已存在的char*您可以这样做:

test_struct->some_string = some_other_char_pointer;

Otherwise, you'll need to allocate memory for it as well: 否则,您还需要为它分配内存:

test_struct->some_string = malloc(...);

You may or may not need to allocate some memory for the string, depending on context. 您可能需要也可能不需要为字符串分配一些内存,具体取决于上下文。 But the code you present allocate all the memory needed to hold that structure. 但是您提供的代码会分配保存该结构所需的所有内存。

Basically, write code that does whatever it is you need to do. 基本上,编写代码可以完成您需要做的任何事情。 Whether you need memory for the string depends on what you're going to do. 你是否需要字符串的内存取决于你将要做什么。

With just the code you've shown, the pointer you allocated doesn't point to anything specific, just like the integers you allocated don't hold any specific values. 只显示您显示的代码,您分配的指针不会指向任何特定的内容,就像您分配的整数不包含任何特定值一样。 Address allocation for the string, if needed, when you set the value of some_string to something useful, probably at the same time you set x and y to something useful. 当你将some_string的值设置为有用的东西时,如果需要,可以在将xy设置为有用的同时为字符串分配地址。

Ok, this bit of code is not doing what you want: 好吧,这段代码没有做你想要的:

struct some_struct *test_struct = malloc(sizeof(some_string);
test_struct->x = 2;
test_struct->y = 3;
test_struct->some_string = "sadlfkajsdflk";

in this case, your *test_struct is now pointing to a 'memory zone' with the typeof some_sring size(I think your some_string is char* ). 在这种情况下,你的*test_struct现在指向一个some_sring size的'memory zone'(我认为你的some_string是char* )。

Malloc(X) gives you X space from your program (or process) virtual memory. Malloc(X)为您的程序(或进程)虚拟内存提供X空间。 When you do: 当你这样做时:

struct some_struct *test_struct; 

You get enough space to store a pointer to some_struct . 您有足够的空间来存储指向some_struct的指针。

If you do: 如果你这样做:

malloc(sizeof(struct some_struct));

You have now reserved struct some_struct space from the virtual memory. 您现在已经从虚拟内存中保留了struct some_struct空间。 But you want to know 'where' that memory is. 但是你想知道记忆的“在哪里”。 Thats why you assign it to the pointer: 这就是为什么你把它分配给指针:

test_struct = malloc (sizeof(struct some_struct));

[EDIT]I'd write this:" To make your compiler happier you should also include a cast in there to tell the compiler that that space allocated by malloc is gonna be used to store a struct some_struct :", giving an example right after. [编辑]我写这个:“为了让你的编译器更快乐,你还应该在那里包含一个struct some_struct来告诉编译器malloc分配的空间将用于存储struct some_struct :”,给出一个示例。 But, in fact, that's not true. 但事实上,这不是真的。 As you can see in the comments below, @chutsu corrected this, and to convince yourself, check this question . 正如您在下面的评论中所看到的,@ chutsu纠正了这一点,并说服自己,检查这个问题 The 'main' reason is that you're taking a lot of risks in doing it for no advantages at all. “主要”原因是你在做这件事时冒了很多风险而根本没有任何优势。
The rest of the code is now corrected: No cast. 其余的代码现在已得到纠正:没有演员表。

A cleaner way to do this would've been typedefing the struct. 更简洁的方法就是输入结构。 Then, your code would look like this: 然后,您的代码将如下所示:

typedef struct some_struct {
    int x;
    int y;
    char *some_string;
}SomeStruct;

SomeStruct *test_struct;
test_struct = malloc(sizeof(SomeStruct));

About the string allocation. 关于字符串分配。 You can think like this: Everything created with malloc(and its brothers calloc, realloc...) needs to be free'd! 您可以这样思考:使用malloc(及其兄弟calloc,realloc ......)创建的所有内容都需要免费! This happens because all the other variables are local to functions, even the main is a function, and this ones are cleaned when the function terminates. 发生这种情况是因为所有其他变量都是函数的局部变量,即使main是函数,当函数终止时也会清除这些变量。

So, after allocating your struct, if you want space for your string, you'll have to allocate space for it. 因此,在分配结构后,如果您想为字符串添加空间,则必须为其分配空间。

test_struct->some_string = malloc((YOUR_STRING_SIZE+SPACE_FOR_THE_STRING_TERMINATOR)*sizeof(char));

with - SPACE_FOR_THE_STRING_TERMINATOR=1 , the \\0 character. with - SPACE_FOR_THE_STRING_TERMINATOR=1\\0字符。

Then, if you want to free test_struct you'll have to free the string first and the struct later, in the reverse order you would lost the pointer to the string and that would leak. 然后,如果你想释放test_struct你将不得不首先释放字符串,然后以相反的顺序释放字符串,你将丢失指向字符串的指针并且会泄漏。 It looks like this: 它看起来像这样:

free(test_struct->some_string);
free(test_struct);

And that's it, you're done. 就是这样,你已经完成了。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM