我有一個函數,它讀取一個csv文件,然後用它的參數更新一個struct
。 我希望能夠遍歷結構元素,所以我轉向了宏。解析csv文件的輸出是文件的行和列的字符串的二維數組。要將字符串轉換爲它們各自的數據類型(目前結構只有int
和char*
)我在宏中使用了一個轉換宏來遍歷結構。在C中的宏中有條件釋放分配的內存
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
感謝所有幫助
UPDATE:
與
CVT_STR strdup(str)
更換
CVT_STR strcpy((char*)malloc(sizeof(char)*(1+strlen(str))), str)
工作,但我不明白爲什麼。也許有人可以啓發我?
你爲什麼要使用宏是爲了這一點,而不是內聯函數[至少在最後一步,你仍然可以使用宏來完成轉換器的擴展,而是傳遞一個函數,而不是宏的「轉換器」。這樣,你可以調試代碼(並且它最有可能不是那麼低效,因爲編譯器會嵌入函數!) – 2013-05-03 20:18:19
你的系統是否缺少'strdup()'? – jxh 2013-05-03 20:20:30
@ user315052:由於現有的答案評論說,的strcpy()不工作,我懷疑這不正是同樣的事情[或做你認爲'strdup'做不同的東西從'的strcpy(的malloc函數(strlen(str)+1),str)' - 當然,它會檢查malloc是否爲null等等,但否則它是一樣的。 – 2013-05-03 20:25:31