c - 在 C 的宏中有条件地释放分配的内存

标签 c memory-management macros

我有一个函数可以读取一个 csv 文件,然后用它的参数更新一个 struct。 我希望能够循环遍历结构元素,所以我求助于宏。解析 csv 文件的输出是文件行和列的二维字符串数组。为了将字符串转换为它们各自的数据类型(目前结构只有 intchar*),我在用于循环访问结构的宏中使用了一个转换宏。

CVT_INT atoi(str)
CVT_STR str

但是,在释放通过解析 csv 文件分配的内存时,如果文件中的字符串没有在开头或结尾分组在一起,就会变得棘手。

csv[row][col]
string|string|int|string|int
string|string|int|string|int
...

for(int row = 0; row < number_of_rows; row++)
    for(int col = 2; col < number_of_cols; col++)
        free(csv[row][col]) // frees string when row[i][3]

我可以确保所有字符串都在结构的开头,但我希望它是动态的,我不想考虑确保数据类型已分组。

我可以释放由 CVT_INT 转换的已分配字符串,但释放 CVT_STR 使用的字符串会导致结构的字符串被释放。我可以想到一种解决方法: 1.分配新空间 2.复制旧字符串 3. 释放旧字符串。

CVT_STR strcpy((char*)malloc(sizeof(char)*(1+strlen(str))), str)

但是,在实现上述内容时,无论何时调用它都会导致崩溃,我不明白为什么。谁能给我解释和解决方法/做同样工作的不同路线?我知道它不是很有效,因此也欢迎提出改进这方面的建议。

另一种可能性,我只能释放 int。但是,我不知道如何在宏中执行此操作,因为它必须返回一个 int。

下面是我调用 cycle-through-struct 宏的示例,其中包含转换宏。

#define STRUCT(type, name, converter) \
        obj->struct.name = converter(csv[row][col++]);
STRUCT_FIELDS
#undef PLAYER

感谢您的帮助

更新:

替换

CVT_STR strcpy((char*)malloc(sizeof(char)*(1+strlen(str))), str)

CVT_STR strdup(str)

有效,但我不明白为什么。也许有人可以启发我?

最佳答案

您需要向 strlen 添加一个不包括尾随 NUL 字节的值。

CVT_STR strcpy((char*)malloc((sizeof(char) * strlen(str)) + 1), str)

或者只是

CVT_STR strcpy((char*)malloc(strlen(str) + 1), str)

关于c - 在 C 的宏中有条件地释放分配的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366487/

相关文章:

c - 具有从 1 到 52 的随机数的矩阵,不重复,但始终保持重复 1 个数字

c - 这个迷你 HashMap 有什么问题?

c - 为什么在访问阻塞/受限内存位置时不会出现段错误?

java - 在 Java 应用程序中使用 JAXBContext 解决内存泄漏

c - 是否可以在 C 中自动生成的变量名中使用 __LINE__ ?

java - 创建 Java 注释以用代码替换标记

c++ - scons搭建环境继承

c - 没有库函数的binaryToDecimal

memory-management - 用Rust中的人造丝和Indicatif进行内存泄漏

c++ - 将点作为参数传递给 C 宏