释放函数中的malloced结构

Sha*_*mer 4 c malloc free pointers

我正在创建一个包含缓冲区功能的源文件,我想将其用于我正在创建的其他库.

它工作正常,但我无法摆脱我在其中一个函数中创建的缓冲区结构.以下片段应该有助于说明我的问题:

C头:

//dbuffer.h
...

typedef struct{
    char *pStorage;
    int *pPosition;
    int next_position;
    int number_of_strings;
    int total_size;
    }DBUFF; 
...
Run Code Online (Sandbox Code Playgroud)

C源:

//dbuffer.c
...
DBUFF* dbuffer_init(char *init_pArray)
    {
    //Find out how many elements the array contains
    int size = sizeof_pArray(init_pArray);                         

    //Initialize buffer structure
    DBUFF *buffer = malloc(sizeof(DBUFF));                                       

    //Initialize the storage
    buffer->pStorage = malloc( (sizeof(char)) * (size) );

    strncpy( &(buffer->pStorage)[0] ,  &init_pArray[0] , size);
    buffer->number_of_strings = 1;

    buffer->total_size = size;
    buffer->next_position = size; //size is the next position because array allocates elements from 0 to (size-1)

    //Initialize the position tracker which keeps record of starting position for each string
    buffer->pPosition = malloc(sizeof(int) * buffer->number_of_strings );
    *(buffer->pPosition + (buffer->number_of_strings -1) ) = 0;

    return buffer;
    }

void dbuffer_destroy(DBUFF *buffer)
    {
    free(buffer->pStorage);
    free(buffer);
    }
...
Run Code Online (Sandbox Code Playgroud)

主要:

#include <stdio.h>
#include <stdlib.h>
#include "dbuffer.h"


int main(int argc, char** argv)
    {
    DBUFF *buff; 

    buff = dbuffer_init("Bring the action");
    dbuffer_add(buff, "Bring the apostles");
    printf("BUFFER CONTENTS: ");
    dbuffer_print(buff); 

    dbuffer_destroy(buff);

    // Looks like it has been succesfully freed because output is garbage
    printf("%s\n", buff->pStorage);   

    //Why am I still able to access struct contents after the pointer has been freed ?
    printf("buff total size: %d\n", buff->total_size);

    return (EXIT_SUCCESS);
    }
Run Code Online (Sandbox Code Playgroud)

输出:

BUFFER CONTENTS: Bring the action/0Bring the apostles/0
??/?
buff total size: 36

RUN SUCCESSFUL (total time: 94ms)
Run Code Online (Sandbox Code Playgroud)

题:

为什么在释放指向结构的指针后,我仍然可以使用下面的行访问struct内容?

printf("buff total size: %d\n", buff->total_size);
Run Code Online (Sandbox Code Playgroud)

Sou*_*osh 7

一旦调用free()了已分配的指针,尝试使用指针调用未定义的行为.你不应该这样做.

引用C11标准,章节§7.22.3.4,free()功能

free()函数使得指向的空间ptr被释放,即可用于进一步分配.[..]

它永远不会说清理,你可能(错误地)期待.

只是为了增加清晰度,调用free()并不总能实际释放分配的物理内存.它只是允许再次分配指针(存储空间)(例如,返回相同的指针)以便连续调用malloc()和族.调用之后free(),该指针不再用于您的程序,但C标准不保证清除已分配的内存.

  • @ShadyProgrammer你看,_cleanup_或_breaking_或_setting为NULL_,这些都不是C标准规定的.:) (2认同)
  • @ShadyProgrammer你__will__留下悬挂指针垃圾.那个"看似工作"的东西就是UB的美丽.:) (2认同)
  • @ShadyProgrammer嗯,有一种常用的编程风格,在调用`free()`之后立即将释放的指针设置为NULL会导致在任何连续尝试使用指针时出现分段错误.这样,您可以收到任何错误的警报. (2认同)

ame*_*yCU 6

如果有任何尝试读取已经存在的内存free可能会导致程序崩溃.或者他们可能不会.就语言而言,其未定义的行为.

您的编译器不会警告您(或阻止您访问它).但是在打电话后显然不这样做free-

printf("buff total size: %d\n", buff->total_size);
Run Code Online (Sandbox Code Playgroud)

作为一种好的做法,您可以将freed指针设置为NULL.

  • @ShadyProgrammer将其设置为"NULL"是一种常见且良好的做法.因此,如果您访问它,通常会得到一个分段错误(**比任何未知问题**更好),它会告诉您发生了错误. (2认同)