在 c 中使用 malloc 实现堆栈 [初学者]

2024-02-02

出于学习目的,我正在用 c 语言实现一个堆栈及其函数。 我添加了一些小的附加功能来第一次使用 malloc 并尝试正确理解它。

我编写了一个最初创建堆栈结构的函数。该函数的返回值是一个具有已分配内存的新结构。在返回值应该是结构的函数中处理 malloc 异常的最佳方法是什么?也许我应该设计不同的功能?我知道 printf 没有完成它的工作;)

我的堆栈结构:

typedef struct Stack
{
    int count;
    int capacity;
    int *data;
} Stack;

创建堆栈实例:

Stack create_stack(int initialcapacity)
{
    Stack new_stack;
    new_stack.count = 0;
    new_stack.capacity = initialcapacity;

    if (!(new_stack.data = malloc(initialcapacity * sizeof(int))))
        printf("not enough memory!");

    return new_stack;
}

使用堆栈的初始容量调用该函数:

Stack stack = create_stack(10);

当我编写删除 Stack 实例的函数时出现了第二个问题。

int delete_stack(Stack *stack)
{
    stack->count = 0;
    stack->capacity = 0;
    free(stack->data);
    stack->data = NULL;
    return 0;
}

我还可以删除结构实例本身吗?仅仅将值设置回 0 并将 int* 直接设置为 NULL 感觉并不完整。

最后但并非最不重要的一点是,我对我的推送功能有疑问。另外,我在这里添加了一些功能,允许我在堆栈已满时将某些内容推送到堆栈上:

void push(int value, Stack *stack)
{   
    if (stack->count == stack->capacity)
    {   
        int *temp = malloc(stack->capacity * sizeof(int));

        int i;
        for (i = 0; i < stack->count; i++)
            temp[i] = stack->data[i];

        free(stack->data);
        stack->data = NULL;

        stack->data = malloc(stack->capacity * 2 * sizeof(int));

        for (i; i > -1; i--)
            stack->data[i] = temp[i];

        free(temp);
        temp = NULL;
        stack->data[stack->count] = value;
        stack->count++;
        stack->capacity = stack->capacity * 2;
    }
    else
    {
        stack->data[stack->count] = value;
        stack->count++;
    }
}

在分配两倍大小的新数组之前,是否有必要“释放”较小的数组并将指针设置为 NULL?

如果我的代码中有任何不必要或编写不正确的内容,请告诉我,我很感激任何使我变得更好的提示。

干杯, 我


我会用指针来做。也就是说,你的create_stack()将使用分配一个新的堆栈结构malloc,然后将值设置为该结构并再次使用 malloc 为该结构分配空间Stack->data。像这样:

Stack* create_stack(int initialcapacity) {
    Stack* new_stack = malloc(sizeof(Stack));

    if (new_stack == NULL)
        return NULL; // return null to tell the caller that we failed

    new_stack->count = 0;
    new_stack->capacity = initialcapacity;
    new_stack->data = malloc(initialcapacity * sizeof(int))

    if (new_stack->data == NULL)
    {
        free(new_stack);
        return NULL;
    }

    return new_stack;
}

这样,我们通过返回 NULL 来“处理”malloc 错误,这样调用者就知道我们失败了。

现在我们已经使用 malloc 来分配 Stack 结构,您可以(阅读:必须)使用它释放它占用的空间free(stack); in delete_stack().

In push(),不需要临时数组,也就是说,你可以立即分配一个更大的数组,将原来的内容复制到其中stack->data, free stack->data并将其设置为新分配的数组:

int *temp = malloc(stack->capacity * 2 * sizeof(int));
// TODO: what if malloc fails?

int i;
for (i = 0; i < stack->count; i++)
    temp[i] = stack->data[i];

free(stack->data);
stack->data = temp;

stack->data[stack->count] = value;
stack->count++;
stack->capacity = stack->capacity * 2;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 c 中使用 malloc 实现堆栈 [初学者] 的相关文章

随机推荐

  • 如何在 UWP 上的 Xamarin.Forms WebView 中启用 WebGL?

    我是 Xamarin Forms 新手 尝试在 Windows 10 x64 v1803 计算机上使用 UWP 使用 WebView 但我不知道如何让它与 WebGL 一起使用 使用 WebGL 的网站要么显示一条消息 您的视频卡不支持 W
  • 是否有符合 IEEE754(r) 标准的 Java 实现?

    是否有任何完全兼容的 IEEE754r 实现可用于 Java 为 Java 选择省略的所有功能提供支持 或者更确切地说 高级语言通常喜欢省略 Traps 粘性旗帜 定向舍入模式 加长 长双 四精度 DPD 密集小数 在任何人弄错之前先澄清一
  • 将 TintColor 设置为 MKAnnotationView 图像

    我正在写一份申请iOS 7 0 我想使用的新功能是 imageWithRenderingMode 我有一个带有以下代码的地图注释 MKAnnotationView annotationView MKAnnotationView annota
  • `?` 运算符只能在返回 `Result` 或 `Option` (或实现 `std::ops::Try` 的其他类型)的函数中使用

    我正在做我的作业 其中包括与 Rust 中的数据库建立连接 我正在使用最新版本的 mysql crate mysql 18 2 0 当我打印池变量时 我的数据库连接成功 我为表学生编写了自己的代码 但收到错误 然后我粘贴文档代码 我收到以下
  • 在 html 页面上一次播放一个视频

    我有一个 html 页面 我使用了视频标签来在线播放视频 我使用了两个视频标签 但是当我播放这两个视频时 两个视频同时播放 我想要一个解决方案 如果我播放一个视频 然后单击第二个视频 那么第一个视频应该暂停 第二个视频开始播放 任何帮助 将
  • 是否可以在 El Capitan 上运行 Xcode 6.3?

    我真的很想尝试 El Capitan 但我不知道是否可以在其上运行旧的 Xcode 因为它现在对我来说至关重要 有人尝试过吗 在终端上运行此命令 Applications Xcode app Contents MacOS Xcode dev
  • Visual Studio 操作系统的条件编译

    我知道有一种方法可以有条件地编译目标框架 例如 if net461 elif 但是有没有一种方法可以针对特定操作系统进行条件编译 像目标 os MAC或目标 os win 如果有人可以指导我如何实现它的文档或教程 第2部分 另外 有没有办法
  • Spring 注释:使用 thymeleaf 对 bean 内部对象属性进行表单验证

    Thymeleaf 有没有办法验证 bean 对象属性中的属性 考虑一下我们确实有一个 Department 类 如下所示 public class Departement Id GeneratedValue strategy Genera
  • 如何获取Web应用程序服务的使用指标数据?

    我正在尝试执行 REST API 以从部署在 Azure 上的 Web 应用程序获取使用指标数据 Hi 我正在尝试执行 REST API 以从部署在 Azure 上的 Web 应用程序获取使用指标数据 https management az
  • php随机名称

    HI 为文件夹创建随机名称的最佳方法是什么 它将用于存储文档的文件夹名称 但是将创建大量文件夹 因此如果可能的话 每次都需要唯一 长度应该在 7 个字符左右 您也可以尝试 PHP 的uniqid http us php net manual
  • ASP.NET WebAPI 将 urlencoded 正文中的空字符串作为 null 传递

    我有一个简单的 ApiController public HttpResponseMessage Put int orderid FromBody Order order Do something useful with order Not
  • EF4 Code First、TDD、CRUD 和事务

    过去 我在创建数据访问 存储库代码时为简单的 CRUD 操作编写了单元测试 如下所示 using var connection new WhateverConnection connectionString connection Open
  • PHP cURL 内容类型未设置

    我想连接一个简单的网络服务 为了发布一些XML 这将在网络服务端正确进行 我需要准备一个正确的请求 我在用cURL对于这样的 try ch curl init if FALSE ch throw new Exception failed t
  • 我该怎么做才能在 WordPress 中获得实际的准备好的语句

    我的公司希望在他们的网站上使用 WordPress 我主要关心的是准备好的语句的使用 根据this https wordpress stackexchange com a 139431 我自己难以置信地阅读了源代码 WordPress 清理
  • 无法将源类型转换为目标类型

    我已经让这个子类实现了我的接口 并且在满足合同方面没有错误 但是 当我尝试在子类的构造函数中设置当前会话时 当它尝试将变量类型与 GetCurrentSession 返回的类型进行比较时 我收到此编译时错误 无法将源类型 IAPISessi
  • SQL Server 2000 - 跳出循环

    我不擅长 SQL Server 2000 我有一个以逗号分隔的 id 列表 我需要查看该 ID 是否存在于表中 如果是这样 我想跳出循环 并将该 ID 保存在可以在存储过程中使用的变量中 这就是我现在正在尝试的 DECLARE coreID
  • 如何使用 std::atomic 实现可重用的线程屏障

    我有 N 个线程执行各种任务 这些线程必须定期与线程屏障同步 如下图所示 有 3 个线程和 8 个任务 表示时间屏障 所有线程必须等到8个任务完成才能再次启动 Thread 1 task1 task6 wait taskB Thread 2
  • 如何一个接一个地运行参数化作业(没有参数)

    我在 Jenkins 有一份工作 有 2 个参数 我想运行另一个没有参数的计划 并从该计划中根据需要多次启动现有计划 新计划需要安排每 15 分钟运行一次 将由 Jenkins 的调度程序选项完成 该计划的代码将 连接到数据库 获取所需的记
  • 如何进行字段枚举迁移 yii2

    我做了字段ENUM 当我使用时结果是错误的yii migrate up在 CMD 窗口上 public function up tableOptions null if this gt db gt driverName mysql tabl
  • 在 c 中使用 malloc 实现堆栈 [初学者]

    出于学习目的 我正在用 c 语言实现一个堆栈及其函数 我添加了一些小的附加功能来第一次使用 malloc 并尝试正确理解它 我编写了一个最初创建堆栈结构的函数 该函数的返回值是一个具有已分配内存的新结构 在返回值应该是结构的函数中处理 ma