字符串的typedef char指针分配

时间:2021-01-09 19:00:06

标签: c string pointers malloc dynamic-memory-allocation

我试图理解包含 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 的部分。是这样发给我的,不过我之前说过,我不知道它是怎么工作的,如果有人能详细给我解释一下,我将不胜感激

2 个答案:

答案 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)

内存有两个区域,一个是本地事物存在的栈,另一个是其他事物存在的堆。堆栈是自动的,因为您的编译器会为您管理它,而堆是您必须通过调用 mallocreallocfree 等来管理的东西。

编译时已知的东西可以存在于栈中,而你在编译时不知道的东西可以存在于堆中,并通过调用 malloc 进行分配、重新分配、释放等、reallocfree

这基本上都归结为分配的内存大小。例如,如果您声明一个 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% 清楚,我很抱歉。