0

csv ファイルを読み取り、そのstructパラメーターで更新する関数があります。構造体の要素を循環できるようにしたかったので、マクロに目を向けました。csv ファイルの解析の出力は、ファイルの行と列の文字列の 2 次元配列です。文字列をそれぞれのデータ型に変換するために (現在、構造体には と しかありませんint) 、構造体char*を循環するために使用されるマクロ内で変換マクロを使用しました。

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 つの回避策を考えることができます: 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)

動作しましたが、理由がわかりません。おそらく誰かが私を啓発することができますか?

4

2 に答える 2