我试图理解包含 typedef char *
的代码,我应该为字符串 "Pointer of"
和 "Redundancy"
分配足够的内存。
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef char* DString;
DString dstring_initialize(const char* str);
int main(void)
{
DString str1, str2;
str1 = dstring_initialize("Pointer of ");
str2 = dstring_initialize("Redundancy ");
return 0;
}
DString dstring_initialize(const char* str)
{
str = malloc((strlen(str)+1)*sizeof(DString));//mycode
return str;//mycode
}
我 100% 确定我做错了。我唯一应该做的就是更改显示 mycode
的部分。是这样发给我的,不过我之前说过,我不知道它是怎么工作的,如果有人能详细给我解释一下,我将不胜感激
答案 0 :(得分:3)
在下面的代码中,您分配了过多的内存:
str = malloc((strlen(str)+1)*sizeof(DString));//mycode
^^^^^^^^^^^^^^
Not needed
您还将 malloc
的返回值分配给输入参数,即您“销毁”了输入。
此外,您永远不会将输入字符串的值复制到分配的内存中。
您需要:
char* res = malloc(strlen(str) + 1);
if (res != NULL)
{
strcpy(res, str);
}
return res;
答案 1 :(得分:1)
内存有两个区域,一个是本地事物存在的栈,另一个是其他事物存在的堆。堆栈是自动的,因为您的编译器会为您管理它,而堆是您必须通过调用 malloc
、realloc
和 free
等来管理的东西。
编译时已知的东西可以存在于栈中,而你在编译时不知道的东西可以存在于堆中,并通过调用 malloc
进行分配、重新分配、释放等、realloc
和 free
。
这基本上都归结为分配的内存大小。例如,如果您声明一个 int,那么该 int 的值会随着您的程序执行而改变,因为它始终存在于 sizeof
an int 的空间中。
但是,如果在程序运行时字符串的长度发生变化,并且您不想分配足够大的东西以始终能够容纳它,那么您可能希望将字符串放入堆中。例如,如果您总是使用诸如 str
之类的东西使其足够大,那么您不需要在堆上为 char str[64]
分配空间,因为您提前分配了该空间。>
就malloc
而言,你要求它分配一定大小的内存,如果可以就返回一个指向它的指针,如果不能就返回NULL
。所以保存malloc
返回的指针的变量存在于栈中,而malloc
分配的内存存在于堆中,不是自动的。即:当您的程序终止时,堆栈中的指针变量被释放,但并未释放堆中存储的实际内存,因此您必须使用 free
释放它。
在 sizeof
的情况下,它告诉 malloc 你想要分配多少,在这种情况下是一个 char
,但它可以是任何解析为一个大小,例如您定义的结构等。所以当您调用 malloc
时,您基本上是在说“给我这么大的东西,给我这么多”。在这种情况下,“给我一个像字符一样大的东西”并给我“strlen(str) + 1
个”。
并且由于字符的大小始终为 1 个字节,并且 strlen
返回 size_t
类型的值,malloc
可以将其作为 char *ptr = malloc(strlen(str) + 1)
使用。但请记住,malloc
返回一个 void
类型的指针,因此您需要将其强制转换为您请求的类型。在这种情况下,您可以将其强制转换为 char*
,如下所示:ptr = (char*)malloc(strlen(str) + 1)
。
另一个错误在另一个答案中描述。但这基本上是 malloc
的工作原理。我不是老师,如果我不是 100% 清楚,我很抱歉。