【问题标题】:Heap Memory and malloc query堆内存和 malloc 查询
【发布时间】:2021-03-02 10:22:20
【问题描述】:

我试图了解动态内存分配,并希望有人能解释为什么以下代码会这样执行。

#include <stdlib.h>
#include <string.h>

char* create_string(void);

int main(){

    char* str1 = NULL;
    char* str2 = NULL;

    str1 = create_string();
    
    str2 = (char*)malloc(11);
    
    str2 = create_string();

    printf("String 1 is: %s", str1);
    
    printf("String 2 is: %s", str2);

    free(str1);

}

char* create_string()
{
    char* stack_str = "TestString";
    char* heap_str = (char*)malloc(strlen(stack_str) + 1);
    strcpy(heap_str, stack_str);
    if(heap_str == NULL)
    {
        printf("Oh no");
        return NULL;
    }

    return heap_str;

}

据我所知,要在堆上分配内存,您必须使用具有分配内存块大小的 malloc,然后使用 strcpy() 或 memcpy() 之类的函数,就像我所做的那样上面的 str2(“TestString”的大小为 malloc 11,空终止符为 1。)

我只是很困惑为什么将 create_string 的结果分配给 str1,它是一个尚未分配内存块的空指针,会产生与 str2 相同的输出。

非常感谢!

【问题讨论】:

  • 这两行str2 = (char*)malloc(11); str2 = create_string(); 内存泄漏。当你将调用create_string() 的结果分配给str2 时,可见的malloc() 分配的内存会丢失。

标签: c memory-management dynamic-memory-allocation


【解决方案1】:

“据我所知,要在堆上分配内存,您必须使用具有以下大小的 malloc...” malloc() 中的大小是无符号整数的字节数。因此语法上str2 = (char*)malloc(11); 是正确的。

str1 和 str2 都从包含“TestString”的堆指向不同的内存位置。这是根据你编程的。然而 str2 = (char*)malloc(11); 返回 11 字节的内存,可以存储字符数据类型,并返回一个指向堆中这个位置的指针。这没有问题。 但是,在您的代码中,当您将 create_string() 指针分配给它时,您已经泄漏了此分配。

【讨论】:

  • 感谢您的回复!我现在有了更好的理解
【解决方案2】:

它并不像你想象的那样工作。

首先,C 有常量字符串,它会被双引号初始化。这些对象在使用时,实际上返回一个指向初始化常量字符串数组位置的指针。

char * ptr="something"   //"something" return a pointer to the location of the string array 
                         // and is assigned to the ptr.

您不需要为常量字符串分配内存,因为它们是由编译器管理的。代码中发生的事情是stack_str 定位到这个由编译器管理的常量字符串数组。所以它总是存在的。您创建一个内存块并将地址存储在heap_str 中,并将stack_str 的内容复制到动态分配的内存中,并返回指针。 实际上,

 str2 = (char*)malloc(11);

不用于任何事情并且被浪费了。希望你能理解。

编辑:在您的create_str() 中,您检查heap_strstrcpy() 之后不是NULL。如果malloc()由于某种原因失败,即使你检查NULL,程序仍然会崩溃。

【讨论】:

  • 感谢您的回复我现在有了更好的理解!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 2010-12-28
相关资源
最近更新 更多