我已经寻找了这个问题的答案,但到目前为止还没有找到任何东西来回答这个特定的问题,所以在这里提问.

我有一些C代码,它动态地为字符串分配空间,并复制位于局部变量中的缓冲区的内容.然后,这个动态分配的字符串存储在一个 struct 中,并在程序的其他地方使用.

现在,当我完成 struct 时,我试图成为一个好公民并释放字符串,然而,当我这样做时,没有失败,程序崩溃了.就我所知,我传入了指向free()的正确指针,如果省略了对free()的调用,那么我已经确认内存泄漏了,那么我做错了什么?

以下是代码的要点.

typedef struct Token {
    size_t length;
    const char* lexeme;

    // Other members
} Token;

// Original string is stored in a stack allocated static buffer:
static char buffer[1024];

// ... stuff here to fill buffer

// Then we generate the dynamic copy of the buffer contents
char* formattedMessage = realloc(NULL, sizeof(char) * strlen(buffer));

// Token is dynamically allocated as needed:
Token* token = realloc(NULL, sizeof(Token));
token->lexeme = strcpy(formattedMessage, buffer);
token->length = strlen(formattedMessage);

// ... Then we do other stuff (which all works, the message is stored in the struct and all is well)

// When we're done we call:
token->lexeme = free((void*)(token->lexeme));

// Which is where the program crashes.

请注意,在实际代码中,我测试了Token-&>lexeme是否为指向字符串的有效指针,并在跟踪时判断内存转储,结果显示传递给Free()的地址是该字符串的正确地址.

在这里撕裂我的头发.

推荐答案

strcpy(a, b)需要a才能指向至少大小为strlen(b) + 1的内存. realloc(NULL, sizeof(char) * strlen(buffer))比所需的少分配一个.

free()不返回任何内容.我甚至不指望《token->lexeme = free((void*)(token->lexeme));》能够编译.


修复起来很容易,但由于新的C23使strdup()成为标准库的一部分,可以考虑使用它来引用和复制string-或roll your own.

// Unnecessary casts removed

char* formattedMessage = strdup(buffer);
if (formattedMessage == NULL) {
  Handle_OutOfMemeory(); // TBD code
}

Token* token = realloc(NULL, sizeof token[0]);
if (token == NULL) {
  Handle_OutOfMemeory(); // TBD code
}
token->lexeme = formattedMessage;
token->length = strlen(formattedMessage);


// ... Then we do other stuff 

// When we're done we call:
free(token->lexeme)
free(token);

风格:malloc(size);realloc(NULL, size);常见得多.

C++相关问答推荐

在C语言中使用scanf()时我无法理解的警告

不会停在空格或换行符上的错误

在c++中使用堆栈的有效括号

LibpCap禁用监视器模式(C、MacOS)

如何在C中使printf不刷新标准输出?

为什么我会收到释放后堆使用错误?

在C++中访问双指针

在C中访问数组中的特定值

我在反转双向链表时遇到问题

C堆栈(使用动态数组)realloc内存泄漏问题

将数组插入数组

通过对一个大的Malloc内存进行切片来使用Malloc的内存片

int * 指向int的哪个字节?

Fscanf打印除退出C代码为1的程序外的所有内容

发送和接收的消息中的Unix域套接字不匹配

在Ubuntu上使用库部署C程序的最佳实践

指向返回 struct 成员的指针,安全吗?

10 个字节对于这个 C 程序返回后跳行的能力有什么意义

可以从指针数组中的值初始化指针吗?

C 中 struct 体自赋值是否安全?特别是如果一侧是指向 struct 的指针?