c 指针,如何将它/它们释放到一个函数中

标签 c function pointers

这是我的代码:

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

void getinfo(unsigned int a, unsigned int b, char **pStr);

int main(){
    unsigned int len_max = 8;
    unsigned int current_size = 0;
    current_size = len_max;
    char *host, *user;
    char *pStr = malloc(len_max);
    if(pStr == NULL){
        perror("\nMemory allocation\n");
        return EXIT_FAILURE;
    }
    printf("Inserisci hostname: ");
    getinfo(len_max, current_size, &pStr);
    if((host=malloc(strlen(pStr)+1 * sizeof(char))) == NULL) abort();
    strncpy(host, pStr, strlen(pStr)+1);
    printf("Inserisci username: ");
    getinfo(len_max, current_size, &pStr);
    if((user=malloc(strlen(pStr)+1 * sizeof(char))) == NULL) abort();
    strncpy(user, pStr, strlen(pStr)+1);
    printf("\nHostname: %s\nUsername: %s\n", host, user);
    free(pStr);
    free(host);
    free(user);
    return EXIT_SUCCESS;
}

void getinfo(unsigned int a, unsigned int b, char **pStr){
    unsigned int i = 0;
    int c = EOF;
    while((c = getchar()) != '\n'){
        (*pStr)[i++] = (char)c;
        if(i == b){
            b = i+a;
            if((*pStr = realloc(*pStr, b)) == NULL){
                perror("\nMemory allocation error\n");
                exit(EXIT_FAILURE);
            }
        }
    }
    (*pStr)[i]='\0';
}

问题是如果 realloc 失败我必须退出(因为我不能分配内存)。但在退出之前,需要释放所有已使用的指针。
问题是,如果函数第一次失败,则只有一个指针需要释放 (pStr)。
但如果第二次失败,则必须释放 2 个指针(pstr 和用户)。
我该如何解决?

最佳答案

如前所述,如果您要退出,那么所有实用的现代操作系统都会在退出前释放分配的内存。并非总是如此。 AmigaDOS 的早期版本 IIRC 在重新启动之前不会自动回收分配的内存。

这是一个简单的案例。还有更复杂的情况,比如你正在解析一个文件到内存中,第 579th 次内存分配失败,你想释放之前的 578 次内存分配,以便用户可以再次尝试。

在这种情况下,您必须记录每个相关的内存分配(这本身可能需要一些内存分配——尽管如果您正在解析文件,您可能有一个包含完整描述的主结构)然后释放所有分配的数据。

在您的示例中,如果这不是 main() 函数并且您没有因内存分配错误而中止,那么您需要确保在退出时释放三个分配的指针功能。标准技巧包括:

  1. 将指针初始化为 0,以便可靠地释放它们:

    char *host = 0;
    char *user = 0;
    
  2. 使用 realloc() 时,不要将结果分配给作为第一个参数传递的表达式:

    不要做:

    ptr = realloc(ptr, newsize);
    

    如果(当)ptr 是对已分配内存的唯一引用并且重新分配失败时,您刚刚泄漏了内存;没有办法释放仍然分配给你的内存。

    使用:

    void *newptr = realloc(oldptr, newsize);
    if (newptr == 0)
        ...recover from memory allocation failure
    oldptr = newptr;
    

    简单版本的问题在于您刚刚丢弃了对已分配内存的唯一引用。 (请注意,您的代码属于危险/泄漏模式)。

  3. 请注意,几乎每个获取资源的函数都必须在返回之前释放获取的资源,或者使程序的其他部分可以使用该资源,以便其他部分可以在完成时释放资源

    “使可用”操作可能会将获取的资源(将其视为内存,但它可以是文件描述符、目录流或大量其他已分配资源中的任何一种)返回给调用函数,或者将其存储在传递给当前函数的结构中,或将其复制到全局或(文件)静态变量,甚至将其存储在(函数)静态变量中,以便再次调用该函数时,它有一些可用资源入场时。

关于c 指针,如何将它/它们释放到一个函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10464173/

相关文章:

c - 从 c 中的用户输入中读取 2 个整数

c - 是不是只安装gcc本身就足以在我的windows机器上构建c语言了?

android - 设置 OpenGL ES 1.1 和我的 android 环境

postgresql - PostgreSQL 中的函数调用行为不当

c++ - (C++) 试图完成一个快速程序,但我不确定哪里出错了?

c++ - 关于c++中二元函数的参数

c - sdl 不断按键

javascript - 什么时候使用递归函数?

c++ - 如何避免访问被删除的内存块时出错?

javascript - 为什么在对象标记中调用函数是有效的?